0

OpenEdge ABL(別名Progress 4GL)で文字列をタイトルケースに変換するにはどうすればよいですか?

CAPS()で大文字、LC()で小文字を取得できることはわかっていますが、大文字(大文字と呼ばれることもあります)関数が見つかりません。

例:

Input           Output
------------    ------------
hello world!    Hello World!
HELLO WORLD!    Hello World!
4

3 に答える 3

4
function titleWord returns character ( input inString as character ):
  return caps( substring( inString, 1, 1 )) + lc( substring( inString, 2 )).
end.

function titleCase returns character ( input inString as character ):

  define variable i as integer no-undo.
  define variable n as integer no-undo.

  define variable outString as character no-undo.

  n = num-entries( inString, " " ).
  do i = 1 to n:
    outString =
      outString +
      ( if i > 1 and i <= n then " " else "" ) +
      titleWord( entry( i, inString, " " ))
    .
  end.

  return outString.

end.

display
  titleCase( "the quick brown fox JUMPED over the lazy dog!" ) format "x(60)"
.
于 2011-04-22T04:40:44.133 に答える
1

私はしばらく前にこれで遊んでいました、そしてトムのような解決策の他に、私は2つのバリエーションを思いつきました。

私が抱えていた問題の1つは、ランタイムや読み取り/書き込みなど、すべての単語がスペースで区切られていないことでした。そのため、このバージョンでは、アルファベット以外の文字を区切り文字として使用するように作成しました。

また、発音区別符号とアクセント付き文字をアルファベットとして数えたかったので、少し複雑になりました。この問題を解決するために、大文字と小文字の2つのバージョンのタイトルを作成します。2つの文字列が同じ場合はアルファベット以外の文字であり、異なる場合はアルファベットです。タイトルは通常非常に短いので、この方法は最初に思われるほど非効率的ではありません。

FUNCTION TitleCase2 RETURNS CHARACTER
  ( pcText AS CHARACTER ) :
/*------------------------------------------------------------------------------
  Purpose: Converts a string to Title Case.  
    Notes: This version takes all non-alphabetic characters as word seperators
           at the expense of a little speed. This affects things like
           D'Arby vs D'arby or Week-End vs Week-end.
------------------------------------------------------------------------------*/

  DEFINE VARIABLE cUText AS CHARACTER   NO-UNDO CASE-SENSITIVE.
  DEFINE VARIABLE cLText AS CHARACTER   NO-UNDO CASE-SENSITIVE.

  DEFINE VARIABLE i      AS INTEGER     NO-UNDO.
  DEFINE VARIABLE lFound AS LOGICAL     NO-UNDO INITIAL TRUE.

  cUText = CAPS(pcText).
  cLText = LC(pcText).
  DO i = 1 TO LENGTH(pcText):
    IF (SUBSTRING(cUText, i, 1)) <> (SUBSTRING(cLText, i, 1)) THEN
    DO:
      IF lFound THEN
      DO:
         SUBSTRING(cLText, i, 1) = (SUBSTRING(cUText, i, 1)).
         lFound = FALSE.
      END.
    END.
    ELSE lFound = TRUE.
  END.
  RETURN cLText.   

END FUNCTION.

もう1つの問題は、タイトルケースが言語固有であると想定されていることです。つまり、動詞と名詞は前置詞と接続詞とは異なる方法で処理されます。タイトルケースのいくつかの可能なルールは次のとおりです。

  1. 最初と最後の単語は常に大文字になります
  2. すべての名詞、動詞(「is」およびその他の形式の「tobe」を含む)、副詞(「than」および「when」を含む)、形容詞(「this」および「that」を含む)、および代名詞(「its」を含む)を大文字にします。 ")。
  3. 動詞句の一部である前置詞を大文字にします。
  4. 小文字の冠詞(a、an、the)。
  5. 小文字の等位接続詞(and、but、for、nor、or)。
  6. 4文字以下の小文字の前置詞。
  7. 不定詞句の小文字の「to」。
  8. 2番目の単語が名詞または固有形容詞である場合、または単語の重みが等しい場合は、複合語で2番目の単語を大文字にします(相互参照、Microsoft以前のソフトウェア、読み取り/書き込みアクセス、実行時)。別の品詞または最初の単語を変更する分詞(ハウツー、離陸)の場合は、2番目の単語を小文字にします。

もちろん、コンピューターに英語を教えずにこれらすべてをコーディングすることはできなかったので、このバージョンを単純な妥協案として作成しました。ほとんどの場合は機能しますが、例外もあります。

FUNCTION TitleCaseE RETURNS CHARACTER
  ( pcText AS CHARACTER ) :
/*------------------------------------------------------------------------------
  Purpose: Converts an English string to Title Case.  
    Notes:          
------------------------------------------------------------------------------*/

  DEFINE VARIABLE i           AS INTEGER     NO-UNDO.
  DEFINE VARIABLE cWord       AS CHARACTER   NO-UNDO.
  DEFINE VARIABLE lFound      AS LOGICAL     NO-UNDO INITIAL TRUE.
  DEFINE VARIABLE iLast       AS INTEGER     NO-UNDO.

  DEFINE VARIABLE cSmallWords AS CHARACTER   NO-UNDO
     INITIAL "and,but,or,for,nor,the,a,an,to,amid,anti,as,at,but,by,down,from,in" + 
             ",into,like,near,of,off,on,onto,over,per,than,to,up,upon,via,with".

  pcText = REPLACE(REPLACE(LC(pcText),"-"," - "),"/"," / ").
  iLast = NUM-ENTRIES(pcText, " ").
  DO i = 1 TO iLast:
    cWord = ENTRY(i, pcText, " ").
    IF LENGTH(cWord) > 0 THEN
      IF i = 1 OR i = iLast OR LOOKUP(cWord, cSmallWords) = 0 THEN
        ENTRY(i, pcText, " ") = CAPS(SUBSTRING(cWord, 1, 1)) + LC(SUBSTRING(cWord, 2)).
  END.

  RETURN REPLACE(REPLACE(pcText," - ","-")," / ","/").   

END FUNCTION.

トムの解決策は私の両方よりもはるかに速いことを言及しなければなりません。必要なものによっては、速度はそれほど重要ではない場合があります。これは、大規模なデータ処理プロセスや長い文字列で使用する可能性が低いためですが、無視しません。ニーズがパフォーマンスの低下を正当化することを確認してください。

于 2012-02-07T13:25:22.237 に答える
1

上記のステートメントの1つの順序が間違っていると思います-

文字列の先頭に「」を追加します。また、<=を<に変更する必要があります。そうしないと、リターン文字列に余分な""が追加されます。

そのはず:

n = num-entries( inString, " " ).
  do i = 1 to n:
    outString =
      outString +
      titleWord( entry( i, inString, " " )) +
      ( if i < n then " " else "" ) +
    .
  end.

少なくともそれは私が思うことです-それはそうあるべきです...

-自分

于 2011-08-03T14:50:31.440 に答える