PHP Regex Word Boundary исключить подчеркивание _

Я использую регулярное выражение границы слова \b, и я пытаюсь сопоставить foo В следующих $sentence но результат не то, что мне нужно, underscore убивает меня, я хочу, чтобы подчеркивание было границей слов, как дефис или пробел:

$sentence = "foo_foo_foo foo-foo_foo";
              X   X   X  YES  X   X

Ожидаемое:

$sentence = "foo_foo_foo foo-foo_foo";
             YES YES YES YES YES YES

Мой код:

preg_match("/\bfoo\b/i", $sentence);

3 ответа

Решение

Вы должны были бы создать границы DIY.

(?:\b|_\K)foo(?=\b|_)

Делает ли это то, что вы хотите?

preg_match_all("/foo/i", $sentence, $matches);
var_dump($matches);

Вы можете вычесть из и использовать однозначные границы слов:

      /(?<![^\W_])foo(?![^\W_])/i

См. Эту демонстрацию регулярного выражения. Примечание \bfoo знак равно (?<!\w)foo а также foo(?!\w) знак равно foo\b, и вычитая _ из \w (что равно [^\W]) приводит к [^\W_].

В PHP вы можете использовать preg_match_all чтобы найти все вхождения:

      preg_match_all("/(?<![^\W_])foo(?![^\W_])/i", $sentence)

Чтобы заменить / удалить все вхождения, вы можете использовать preg_replace:

      preg_replace("/(?<![^\W_])foo(?![^\W_])/i", "YES", $sentence)

См. Демонстрацию PHP онлайн:

      $sentence = "foo_foo_foo foo-foo_foo";
if (preg_match_all("/(?<![^\W_])foo(?![^\W_])/i", $sentence, $matches)) {
    print_r($matches[0]);
}
// => Array( [0] => foo [1] => foo [2] => foo [3] => foo [4] => foo [5] => foo)
echo PHP_EOL . preg_replace("/(?<![^\W_])foo(?![^\W_])/i", "YES", $sentence);
// => YES_YES_YES YES-YES_YES
Другие вопросы по тегам