PHP正则表达式单词边界排除下划线_。

6

我正在使用正则表达式的单词边界\b,并尝试在以下句子$sentence中匹配foo,但结果不是我需要的,下划线让我很困扰,我希望下划线像连字符或空格一样成为单词边界:

$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);

你尝试过在线搜索吗? - Anonymous
我在 Google 上找不到这个特定的问题。 - Sunny
你能否在这里使用 preg_split 而不是 preg_match - sectus
@Sunny 在网上有很多关于这个问题的文章,相关问题部分也有许多不同的问题与此相关。 - Anonymous
@sectus 应该是 preg_match :( - Sunny
3个回答

13

你需要创建自定义边界。

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

0

这个是否符合你的要求?

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

不行,因为它也会匹配 foobar,而我只想要完整的单词。 - Sunny

0

您可以从\w中减去_并使用明确的单词边界:

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

请查看这个正则表达式演示。注意\bfoo = (?<!\w)foofoo(?!\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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接