如何在OpenEdge ABL / Progress 4GL中将字符串转换为标题大小写?

时间:2011-04-21 21:50:48

标签: progress-4gl openedge

如何在OpenEdge ABL(又名Progress 4GL)中将字符串转换为标题大小写?

我知道我可以使用CAPS()获得大写,使用LC()获得小写,但我找不到标题大小写(有时称为正确大小写)函数。

示例:

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

3 个答案:

答案 0 :(得分:3)

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)"
.

答案 1 :(得分:1)

我认为上述其中一个陈述的顺序不正确 -

你将在字符串的开头添加一个额外的“”!还需要将&lt; =更改为&lt;或者你将在你的返回字符串中添加额外的“”。

应该是:

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

至少那是我想的 - 应该是......

-Me

答案 2 :(得分:1)

我一会儿玩这个,除了类似汤姆的解决方案之外,我想出了两个变化。

我遇到的一个问题是并非所有单词都被空格分隔,例如运行时和读/写,所以我写了这个版本,使用任何非字母字符作为分隔符。

我还想把变音符号和重音字符算作字母,所以它变得有点复杂。为了解决这个问题,我创建了两个版本的标题,一个是大写,一个是小写。两个字符串相同的地方,它是一个非字母字符,它们是不同的,它是按字母顺序排列的。标题通常很短,所以这种方法并不像最初看起来那么低效。

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. 第一个也是最后一个字总是大写
  2. 大写所有名词,动词(包括“是”和其他形式的“to 是“),副词(包括”比“和”何时“),形容词(包括 “this”和“that”)和代词(包括“its”)。
  3. 大写作为动词短语一部分的介词。
  4. 小写文章(a,an,the)。
  5. 小写坐标连词(和,但是,for,nor,或)。
  6. 四个或更少字母的小写介词。
  7. 在一个不定式短语中小写“到”。
  8. 如果它是名词或者,则将复合词中的第二个词大写 适当的形容词或单词具有相同的权重(交叉引用, Microsoft之前的软件,读/写访问,运行时)。小写的 第二个词,如果它是另一个词性或分词 修改第一个单词(How-to,Take-off)。
  9. 我当然不能在没有教授计算机英语的情况下对所有这些进行编码,所以我创建这个版本是一个简单的粗略妥协;它适用于大多数情况,但也有例外。

    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.
    

    我不得不提到Tom的解决方案比我的解决方案快得多。根据您的需要,您可能会发现速度并不重要,因为您不太可能在大型数据处理过程中使用它或使用长字符串,但我不会忽略它。确保您的需求证明性能损失是合理的。