[英]Select two consecutive words by regular expression
因为,我是正则表达式的新手。 我想做一个正则表达式来选择两个连续的单词。
例如,当我输入以下短语时:“ Hello people #RegularExpression很烂!”
它必须返回以下几句话:
-大家好
人#RegularExpression
-#RegularExpression很烂!
我尝试了这个/\\w\\s\\w/i
但是它没有用:(
$s = "Hello people #RegularExpression sucks!";
preg_match_all('~(?=(\S+\s+\S+))\S+\s+~', $s, $matches);
print_r($matches[1]);
输出:
Array
(
[0] => Hello people
[1] => people #RegularExpression
[2] => #RegularExpression sucks!
)
说明:
\\S+
匹配一个或多个非空白字符。 您的\\w
错误是由两个原因造成的:它仅匹配一个字符; 并且仅匹配一个所谓的单词字符 (相当于[A-Za-z0-9_]
)。 在此测试用例中,没有必要将+
添加到\\s
,但是没有理由不添加+,而多余的空白确实可以潜入真实世界中的文本中。 (但是请确保并添加+
而不是*
;其中必须至少包含一个空格字符。)
(?=...)
是一个积极的前瞻 。 您可以使用它们来检查是否有可能在不提高匹配位置的情况下在当前匹配位置匹配包含的子表达式。 然后,通常,您继续进行操作并匹配不同的子表达式,而不是先行匹配。
这是一个棘手的问题:尽管不消耗与前瞻性子表达式匹配的字符,但是子表达式中的任何捕获组都照常工作。 正则表达式中的前瞻(?=(\\S+\\s+\\S+))
匹配并捕获下一个两个单词的序列。 然后(假定先行成功) \\S+\\s+
以正常方式匹配,为下一次尝试正确设置匹配位置。
此技术应在任何支持捕获组和超前的正则表达式中起作用。 其中包括PHP以及所有其他主要语言(Perl,JavaScript,.NET,Python,Java ...)。 每个匹配项仅访问第一个捕获组的内容的技术在一种语言和另一种语言之间千差万别,但是PHP通过$matches[1]
使其变得容易。
您的正则表达式实际上将匹配两个以空格分隔的字母。 因此,使用您的输入,您将获得op
和ns
。 这样做的另一个问题是对字符串执行全局正则表达式搜索,以返回不重叠的实例。 因此,正确的正则表达式可以返回Hello people
, #RegularExpression sucks!
,但它不会返回people #RegularExpression
因为它与Hello people
people #RegularExpression
重叠。 第三个问题是如何定义单词? \\w
原子使用的经典定义是字母数字或下划线。 因此, #
#RegularExpression
将不匹配,因为#
不是单词字符。
总而言之,听起来您真正想做的只是将字符串分割成空格,然后您可以自己收集所有单词对。 您可以使用诸如preg_split('/\\s+/', $str)
类的方法进行拆分,以返回所有用空格分隔的单词的数组,然后可以根据需要迭代该数组。
我很确定可以使用正则表达式,但是泡菜是正则表达式消耗它们匹配的手表,因此“返回”以获取重叠的匹配是一件棘手的事情。 正则表达式不是正确的工具; 锤子不会吮吸,因为它不能(正确地)拧紧螺丝。
如果我是你,我只会做:
$str = "Hello people #RegularExpression does not suck!";
$arr = explode(' ', $str);
for ($i=0; $i<count($arr) - 1; $i++) {
echo implode(' ', array_slice($arr, $i, 2)) . "\n";
}
输出:
Hello people
people #RegularExpression
#RegularExpression does
does not
not suck!
就像其他人说的那样,在标准pcre regex中似乎不可能( 编辑:糟糕,这是错误的,请参阅Alan的回答 ),您最好选择另一种策略。
让我补充一点,它似乎存在一种实验性和棘手的解决方案:回溯动词。
请参阅文档pcre.org/pcre.txt中的“回溯控制”部分
这种模式应该起作用:
/[^\s]+\s[^\s]+/i
匹配每个非空白字符,后跟单个空白字符和其他非空白字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.