正则表达式PHP单词边界?

正则表达式PHP单词边界?,php,regex,Php,Regex,为什么这个正则表达式不: $match = preg_grep("%^\w{2,5}\b[a-zA-Z]%", $randarray); 返回“大街123号”?从$randarray=array('123大街') 这些单词边界让我困惑。当我键入%^\w{2,5}\b[a-zA-Z]\b%时,也不会发生任何事情……为什么?单词边界不是字符 单词边界是\b。单词边界不是空格,也不是任何字符。它是一个单词和一个非单词之间的过渡,所以它实际上是字符之间的一个点,而不是字符本身 如果你想匹配123 Ma

为什么这个正则表达式不:

$match = preg_grep("%^\w{2,5}\b[a-zA-Z]%", $randarray);
返回“大街123号”?从$randarray=array('123大街')


这些单词边界让我困惑。当我键入
%^\w{2,5}\b[a-zA-Z]\b%
时,也不会发生任何事情……为什么?

单词边界不是字符

单词边界是
\b
。单词边界不是空格,也不是任何字符。它是一个单词和一个非单词之间的过渡,所以它实际上是字符之间的一个点,而不是字符本身

如果你想匹配123 Main street,你必须匹配一个数字序列,后跟一个空格,后跟(我想)一个或多个单词。大概是

/^\w{2,5}(\s[a-zA-Z]+\b)+/
因此,第二组匹配一个空格(位于街道编号或名称的前一个单词之后)、一系列字母字符和一个单词边界。它将与“123大街”相匹配,仅与“大街”相匹配

贪婪/不贪婪

默认情况下,正则表达式是贪婪的,将匹配尽可能多的字符。因此,在本例中,实际上根本不需要单词边界。如果它能匹配街道,它就不会匹配街道。因此,下面的正则表达式将具有与上面相同的效果(除非添加一些ungray修饰符)

但是对于一个不规则的正则表达式来说,它很重要。比较

^\w{2,5}(\s[a-zA-Z]+?)+

第一个将匹配
123 M
,而第二个将再次匹配
123 Main street

测试您的正则表达式


如果您想测试此正则表达式或其他正则表达式,可以访问它,它允许您测试正则表达式,以查看它们如何与几个
preg.*
函数一起工作。

假设您想验证您的主题“以2到5个字符长的单词开头”

preg_match('%^\w{2,5}\b[a-zA-Z]*%','123 Main Street')

(您缺少
*

您的表达式:

^\w{2,5}\b[a-zA-Z]
将匹配“123大街”,直到这里:

123大街
^
请注意,单词边界实际上根本不占用任何空间,因此插入符号位于它后面的字符处

此时,它尝试匹配
[a-zA-Z]
,但失败了。相反,您应该匹配空间:

^\w{2,5}\s+[a-zA-Z]

由于
\w
\s
之间的转换,单词边界将自然出现,因此我将其去掉。

您希望匹配什么?好的,谢谢,还有一个问题是,在我的例子“123大街”中,123和空格之间的转换不是单词边界,因为空格是非单词对吗?这算是单词边界吗?不,空格本身就是一个字符。单词边界不是字符,而是字符之间的位置。使用单词边界来确保匹配整个单词。例如,如果我想让一个单词以“street”结尾,我可以写
[a-z]*street\b
。它将匹配以street结尾的任何(字母-小写)单词,不管后面是否有空格或任何其他非单词字母,但它不会匹配streets。@AlexAdic special“三个不同的位置符合单词边界”。我试图为答案添加一些额外的信息和更多的结构。谢谢你,GolezTrol,这是我一直在寻找的答案。
*
改变了表达式的语义;它至少应该是
+
,但是它也会不匹配。@Ja͢ck我理解你的观点,但当我以“假设”开始我的发言时,我认为否决票是不公平的。我的RegExp不符合我的假设吗?不,不符合\b是单词边界,不是空格。您的正则表达式不会读取超过空格的内容,因为它允许有0个长度的单词,所以它只匹配
123
,而不是
123 Main Street
。您已经知道OP想要匹配什么,所以不必假设其他情况。另外,如果这是您的假设,为什么不使用表达式
\w{2,5}\b
?@Jack在编写时我没有(OP想要匹配的内容),但是,我还是不做说明
^\w{2,5}\b
允许字符不在
[a-zA-Z]
\b
后面。
^\w{2,5}\b[a-zA-Z]
^\w{2,5}\s+[a-zA-Z]