【问题标题】:How do I convert strings to title case in OpenEdge ABL / Progress 4GL?如何在 OpenEdge ABL / Progress 4GL 中将字符串转换为标题大小写?
【发布时间】:2011-04-21 21:50:48
【问题描述】:

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

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

例子:

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

【问题讨论】:

    标签: progress-4gl openedge


    【解决方案1】:
    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】:

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

    您将在字符串的开头添加一个额外的“”!还需要将

    应该是:

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

    至少我认为应该是这样的......

    -我

    【讨论】:

      【解决方案3】:

      前段时间我在玩这个,除了类似于 Tom 的解决方案外,我还想出了两个变体。

      我遇到的一个问题是并非所有单词都用空格分隔,例如 Run-Time 和 Read/Write,所以我编写了这个版本以使用任何非字母字符作为分隔符。

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

      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. 将所有名词、动词(包括“is”和其他形式的“to be")、副词(包括“than”和“when”)、形容词(包括 “this”和“that”)和代词(包括“its”)。
      3. 将属于动词短语的介词大写。
      4. 小写冠词(a、an、the)。
      5. 小写并列连词(and、but、for、nor 或 or)。
      6. 四个或更少字母的小写介词。
      7. 不定式短语中的小写“to”。
      8. 如果复合词中的第二个词是名词或 适当的形容词或单词具有相同的权重(交叉引用, Pre-Microsoft 软件、读/写访问、运行时)。小写 第二个词,如果它是另一个词性或分词 修改第一个单词(How-to、Take-off)。

      如果不教计算机英语,我当然不能编写所有这些代码,所以我创建了这个版本作为一个简单但粗略的折衷方案;它在大多数情况下都有效,但也有例外。

      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-03-19
        • 2014-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-15
        相关资源
        最近更新 更多