Я пытаюсь использовать 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|$)
для пробелов или конца строки — приемлемо ли это, если нет, как это сделать?
Если вы делаете этот:
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);
Что вы можете видеть, как все это работает Вот.
Вы можете сделать это, используя негативные взгляды:
/(?<!\S)st\.?(?!\S)/i
Таким образом, вам не нужно сопоставлять пробелы вокруг части, которую нужно заменить:
$str = preg_replace('/(?<!\S)st\.?(?!\S)/i', 'Street', $str);