regex — PHP Array str_replace Целое слово

я делаю str_replace на очень долго string и мой $search является array,

$search = array(
" tag_name_item ",
" tag_name_item_category ");

$replace = array(
" tag_name_item{$suffix} ",
" tag_name_item_category{$suffix} ");

echo str_replace($search, $replace, $my_really_long_string);

Причина, по которой я добавил пробелы на обоих $search а также $replace потому что я хочу, чтобы соответствовать только целые слова. Как вы уже догадались из моего кода выше, если бы я убрал пробелы и моя действительно длинная строка:

...
tag_name_item ...
tag_name_item_category ...
...

Тогда я бы получил что-то вроде

...
tag_name_item_sfx ...
tag_name_item_sfx_category ...
...

Это неправильно, потому что я хочу следующий результат:

...
tag_name_item_sfx ...
tag_name_item_category_sfx ...
...

Так что не так?

Ничего особенного, это работает. Но мне это не нравится. Выглядит грязно, плохо закодировано, неэффективно.

Я понял, что могу сделать что-то подобное, используя регулярные выражения, используя \b модификатор, но я не хорошо с регулярным выражением, и поэтому я не знаю, как preg_replace,

1

Решение

Возможный подход с использованием регулярных выражений будет выглядеть следующим образом:

$result = preg_replace(
'/\b(tag_name_item(_category)?)\b/',
'$1' . $suffix,
$string
);

Как это устроено:

  • \b: Как вы говорите, границы слов, это для того, чтобы мы соответствовали только словам, а не частям слова
  • (: Мы хотим использовать часть нашего совпадения в строке замены (tag_name_index должен быть заменен на себя + суффикс). Вот почему мы используем группу совпадений, поэтому мы можем вернуться к совпадению в строке замены
  • tag_name_index буквальное совпадение для этой строки.
  • (_category)?: Еще одно буквальное совпадение, сгруппированное и сделанное необязательным благодаря использованию ? оператор. Это гарантирует, что мы сопоставляем оба tag_name_item а также tag_name_item_category
  • ): конец первой группы (необязательный _category матч это вторая группа). Эта группа, по сути, содержит весь матч, который мы собираемся заменить
  • \b: опять граница слова

Эти матчи заменяются '$1' . $suffix, $1 является ссылкой на первую группу соответствия (все, что находится внутри внешних скобок в выражении). Вы можете обратиться ко второй группе, используя $2, но мы не заинтересованы в этой группе прямо сейчас.

Вот и все, что нужно сделать


Более общий:

Итак, вы пытаетесь добавить суффикс всех строк, начиная с tag_nameЗа которым, судя по вашему примеру, может следовать любое количество слов snake_cased. Более общее регулярное выражение для этого будет выглядеть примерно так:

$result = preg_replace(
'/\b(tag_name[a-z_]*)\b/',
'$1' . $suffix,
$string
);

Как и раньше, использование \b, () и tag_name буквальное остается неизменным. что изменилось это:

  • [a-z_]*: Это класс персонажа. Он соответствует символам a-z (от a до z) и подчеркивает ноль или более раз (*). Это соответствует _item а также _item_categoryтак же, как это будет соответствовать _foo_bar_zar_fefe,

Эти регулярные выражения с учетом регистра, если вы хотите сопоставить такие вещи, как tag_name_XYZвы, вероятно, захотите использовать i флаг (без учета регистра): /\b(tag_name[a-z_]*)\b/i

Как и прежде, все совпадения группируются и используются в строке замены, к которой мы добавляем $suffixчто бы это ни было

1

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

Чтобы избежать проблемы, вы можете использовать strtr который разбирает строку только один раз и выбирает самое длинное совпадение:

$pairs = [ " tag_name_item "          => " tag_name_item{$suffix} ",
" tag_name_item_category " => " tag_name_item_category{$suffix} " ];

$result = strtr($str, $pairs);
0

Эта функция заменяет все слово целиком, но не подстроку, элементом массива, который соответствует слову

<?PHP
function removePrepositions($text){

$propositions=array('/\b,\b/i','/\bthe\b/i','/\bor\b/i');

if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));

}
$retval = trim($text);

}
return $retval;
}

?>

Увидеть весь пример

0
По вопросам рекламы [email protected]