я делаю 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
,
Возможный подход с использованием регулярных выражений будет выглядеть следующим образом:
$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
что бы это ни было
Чтобы избежать проблемы, вы можете использовать strtr
который разбирает строку только один раз и выбирает самое длинное совпадение:
$pairs = [ " tag_name_item " => " tag_name_item{$suffix} ",
" tag_name_item_category " => " tag_name_item_category{$suffix} " ];
$result = strtr($str, $pairs);
Эта функция заменяет все слово целиком, но не подстроку, элементом массива, который соответствует слову
<?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;
}
?>
Увидеть весь пример