Использование preg_match для расширения аббревиатур

Я пытаюсь использовать preg_match Выражение в php возвращает общие сокращения, а затем заменяет их полной версией слова (т. е. «St.» становится «Street») перед добавлением их в базу данных.

Это означает, что он должен соответствовать пробелу перед аббревиатурой, полной аббревиатурой, необязательным «.» И либо концом строки, либо пробелом (чтобы не возвращать совпадение для «Station»). Я пробовал:

preg_match( "#\s(S|s)t\.?\s#" , $my_string , $matches )
preg_match( "#(\s(S|s)t\.?)+(\s|$)+#" , $my_string , $matches )
preg_match( "#(\s{1}(S|s){1}t{1}\.?){1}\s{1}#" , $my_string , $matches )

Я получаю матчи, которые не ожидаю и не знаю почему.
когда $my_string = "My St. and something else".:

1-е $ соответствует: array ( " St." , "S" )

2-й: array ( " St." , " St." , "S", " " )

3-й: array ( " St.", " St." , "S" )

Возвращает соответствующие совпадения в случае «St.» заменяется на «st.», «St» или «st.».

Как мне сузить совпадения только до одного экземпляра в этих случаях?

Функционально соответствующая замена, кажется, работает, потому что она заменяет только первое совпадение, но я чувствую, что должен быть в состоянии сузить до одного совпадения.

И второстепенный вопрос, во втором preg_match() выше я пытаюсь использовать (\s|$) для пробелов или конца строки — приемлемо ли это, если нет, как это сделать?

0

Решение

Если вы делаете этот:

 preg_match( "#(?<=\s)([Ss]t\.?)\s#" , $my_string , $matches );

первый элемент массива $ match будет иметь «St.» (полное совпадение), а второй элемент будет иметь «St.», часть, которую вы хотите заменить.

Если вы предпочитаете совпадать с предыдущим пробелом и избегать последнего:

preg_match( "#(\s[Ss]t\.?)(?>\s)#" , $my_string , $matches );

Вы можете увидеть второй работает Вот.

Ну, ради полноты, я бы сделал что-то более или менее подобное:

$patterns     = [];
$replacements = [];
$string       = "The St. Leicester Square is near a statue located somewhere.
The train left the St";

$patterns[]     = "#(?<=\s)([Ss]t\.?)(?=\s|$)#m";
$replacements[] = "station";

echo preg_replace($patterns, $replacements, $string);

Что вы можете видеть, как все это работает Вот.

0

Другие решения

Вы можете сделать это, используя негативные взгляды:

/(?<!\S)st\.?(?!\S)/i

Таким образом, вам не нужно сопоставлять пробелы вокруг части, которую нужно заменить:

$str = preg_replace('/(?<!\S)st\.?(?!\S)/i', 'Street', $str);
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector