Regex Преобразование строковых сокращений в заглавный регистр

0

В рамках простой функции очистки/прошивки URL-адресов я расширяю, мне нужно сделать такие преобразования, как:

Original               Converted
---------------------------------------------
USAMarch               UsaMarch
FETExaminations        FetExaminations      *
AnotherABBRString      AnotherAbbrString
LastONE                LastOne

(Это всего лишь примеры, за исключением второго, что и заставило меня сделать это в первую очередь.)

Я предполагаю, что мне нужно использовать preg_replace_callback чтобы определить положение любых аббревиатур и preg_replace_callback их в соответствие.

У меня нет туманности, с чего начать. Кто-нибудь знает, что я могу сделать, чтобы понять это правильно?

Обновить

Хорошо, у меня это до сих пор:

$input = preg_replace_callback("~([A-Z])([A-Z]+)([^a-z])([a-z]|)~",
function ($captures) {
   return $captures[1].strtolower($captures[2]).$captures[3].$captures[4];
},
$input);

К сожалению, однако, он не работает со строками, где последнее сокращение:

This                   Becomes
---------------------------------------------
LastONE                LastOnE

Полагаю, я проверю конец неправильно. Кроме того, эта попытка не является рекурсивной. Как мне это сделать?

  • 1
    Можете ли вы поделиться тем, что вы, возможно, пытались?
  • 0
    Извините, но я не смог понять, с чего начать ... Все, что я придумал, не сработает. Например, я мог бы сопоставить две заглавные буквы в последовательности, а затем заменить вторую ее нижним эквивалентом, но это сломает новые слова ...
Показать ещё 6 комментариев
Теги:
callback

1 ответ

1
Лучший ответ

Они работают с вашими примерами.

Даже находит одиночные шапки.

 # Find:  '/([A-Z])([A-Z]+)(?=[A-Z]|\b)/'
 # Replace:  $1 . tolower($2)

 ( [A-Z] )                     # (1), Upper case
 ( [A-Z]+ )                    # (2), 1 or more upper case
 (?=                           # Lookahead assertion
      [A-Z]                         # Upper case
   |                              # or,
      \b                            # Word boundry
 )

Или, требуется нижний регистр перед возможными концевыми крышками

 # Find:  '/([a-z])?([A-Z])([A-Z]+)(?=[A-Z]|(?(1)\b|(?!)))/'
 # Replace:  $1$2 . tolower($3)

 ( [a-z] )?                    # (1), optional lower case
 ( [A-Z] )                     # (2), Upper case
 ( [A-Z]+ )                    # (3), 1 or more upper case
 (?=                           # Lookahead assertion
      [A-Z]                         # Upper case
   |                              # or
      (?(1)                         # Conditional, does lower case precede this ?
           \b                            # yes, match boundry
        |  (?!)                          # or fail, this is a stand alone cap's
      )
 )
  • 0
    Это довольно превосходно - спасибо! Это работает для большинства случаев, включая те, которые я не перечислил в своем вопросе.
  • 1
    @MikeAnthony - Пожалуйста, рад, что ты начал.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню