Как преобразовать строки в регистр заголовков в OpenEdge ABL / Progress 4GL? - PullRequest
0 голосов
/ 22 апреля 2011

Как преобразовать строку в регистр заголовка в OpenEdge ABL (он же Progress 4GL)?

Я знаю, что могу получить верхний регистр с CAPS (), и нижний регистр с LC (), но я могуне может найти заглавную (иногда называемую правильным регистром) функцию.

Примеры:

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

Ответы [ 3 ]

3 голосов
/ 22 апреля 2011
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 голос
/ 07 февраля 2012

Я играл с этим некоторое время назад, и помимо решения, похожего на решение Тома, я придумал два варианта.

Одна из моих проблем заключалась в том, что не все слова разделяются пробелом,такие как 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. С заглавными буквами все существительные, глаголы (включая «есть» и другие формы «быть»), наречия (включая «чем» и «когда»), прилагательные (включая «это» и «то») и местоимения (включая «свое»).
  3. С заглавными буквами предлоги, являющиеся частью глагольной фразы.
  4. Строчные буквы (a, an, the).
  5. Строчные координатные союзы (и, но, для, ни, или).
  6. Строчные предлоги из четырех или менее букв.
  7. Строчная буква «to» в инфинитивной фразе.
  8. Заглавная буква второго слова в составных словах, если это существительное или правильное прилагательное или слова имеют одинаковый вес (перекрестная ссылка, пре-Программное обеспечение 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.

Я должен упомянуть, что решение Тома намного быстрее, чем оба моих.В зависимости от того, что вам нужно, вы можете обнаружить, что скорость не так важна, поскольку вы вряд ли будете использовать ее в больших процессах обработки данных или с длинными строками, но я бы не стал игнорировать это.Убедитесь, что ваши потребности оправдывают потерю производительности.

1 голос
/ 03 августа 2011

Я думаю, что порядок одного из этих утверждений выше -

Вы будете добавлять дополнительные "" в начале строки! Также необходимо изменить <= на <, иначе вы добавите "" в возвращаемую строку. </p>

Должно быть:

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

По крайней мере, я так думаю ...

-Мне

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...