OpenEdge ABL(別名Progress 4GL)で文字列をタイトルケースに変換するにはどうすればよいですか?
CAPS()で大文字、LC()で小文字を取得できることはわかっていますが、大文字(大文字と呼ばれることもあります)関数が見つかりません。
例:
Input Output
------------ ------------
hello world! Hello World!
HELLO WORLD! Hello World!
OpenEdge ABL(別名Progress 4GL)で文字列をタイトルケースに変換するにはどうすればよいですか?
CAPS()で大文字、LC()で小文字を取得できることはわかっていますが、大文字(大文字と呼ばれることもあります)関数が見つかりません。
例:
Input Output
------------ ------------
hello world! Hello World!
HELLO WORLD! Hello World!
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)"
.
私はしばらく前にこれで遊んでいました、そしてトムのような解決策の他に、私は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つの問題は、タイトルケースが言語固有であると想定されていることです。つまり、動詞と名詞は前置詞と接続詞とは異なる方法で処理されます。タイトルケースのいくつかの可能なルールは次のとおりです。
もちろん、コンピューターに英語を教えずにこれらすべてをコーディングすることはできなかったので、このバージョンを単純な妥協案として作成しました。ほとんどの場合は機能しますが、例外もあります。
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.
トムの解決策は私の両方よりもはるかに速いことを言及しなければなりません。必要なものによっては、速度はそれほど重要ではない場合があります。これは、大規模なデータ処理プロセスや長い文字列で使用する可能性が低いためですが、無視しません。ニーズがパフォーマンスの低下を正当化することを確認してください。
上記のステートメントの1つの順序が間違っていると思います-
文字列の先頭に「」を追加します。また、<=を<に変更する必要があります。そうしないと、リターン文字列に余分な""が追加されます。
そのはず:
n = num-entries( inString, " " ).
do i = 1 to n:
outString =
outString +
titleWord( entry( i, inString, " " )) +
( if i < n then " " else "" ) +
.
end.
少なくともそれは私が思うことです-それはそうあるべきです...
-自分