PHP正则表达式匹配或者或不使用支架一个字?
我现在的模式是这样的:PHP正则表达式匹配或者或不使用支架一个字?
pattern=("/(.*)(\bIf you want\b)(.*)/iu");
但随着:
preg_replace($pattern, '$1*$2*$3', $result);
所以这三个部分必须更换,因为它们是由$ 1,$ 2和$ 3,但我想允许一些更大的灵活性这样我就可以检测出例如这两行:
If you want
If I want
所以我可以简单地这样做:
pattern=("/(.*)(\bIf (I|you) want\b)(.*)/iu");
但因为我需要更换$ 1,$ 2和$ 3中产生了一个问题。该模式是动态插入,因此都不同:
$pattern = "/(.*)(\b".$value."\b)(.*)/iu";
的$值有时也有像上面的例子修饰符“如果(你|我)希望”,但其他的模式可能是简单地“接下来发生的事情”没有修饰符。所以额外的括号会导致一个问题,但我找不到另一种方法来做到这一点。
编辑:请注意,这里的问题是$ 1,$ 2和$ 3都的preg_replace。有了这样
"/(.*)(\bwhat happened next\b)(.*)/iu"
模式这个经过精细,但像
"/(.*)(\bIf (I|you) want\b)(.*)/iu"
额外的支架也不会以$ 1,$ 2和$ 3都的preg_replace正常更换。
而且我知道它可以像这样
If you want|If I want
但它不是特别雄辩做!
对于刚刚匹配我还是你,这个工作对我来说:
$pattern=("/(.*)(\bIf (?:i|you) want\b)(.*)/iu");
我认为人们只是回答得太快。我的问题的全部内容是没有括号。不知道是否可以完成,但我已经在这里列出了你的解决方案,在我的问题....我显然知道如何做到这一点,但添加额外的括号是首先导致问题的原因。 – Hasen
但这不是正常的括号,请注意'?:i'的用户。这使得这个括号为“非捕捉括号组” –
你的问题是,你不能依靠编号捕获组为其编号可能会有所不同,因为用户定义的模式部分可能包含任意数量的编号捕获组。
出路可以通过使用命名为捕获组。他们唯一的麻烦是PHP不支持替换模式中的命名反向引用。它可以通过preg_replace_callback
功能工作围绕:
$s = 'text If you want this';
echo preg_replace_callback("/(?<start>.*)(?<mid>If (I|you) want)(?<end>.*)/siu", function($m) {
return $m['start'].'*'.$m['mid'].'*'.$m['end'];
}, $s);
// => text *If you want* this
见PHP demo。
您可能会“模糊”组名,使他们无法与用户自定义模式发生冲突。或者让用户知道模式中不能使用哪些名称。
注意s
修改将使.
匹配换行也是如此。
将上述溶液将mid
组的最后发生匹配作为第一start
图案是贪婪点图案。如果您的字符串包含多个匹配项,并且您希望mid
组匹配字符串中的第一个匹配项,请将(?<start>.*)
替换为(?<start>.*?)
。否则,您需要决定算法应该是什么样的。
您的意思是'$ value'是否可以包含用户定义的模式?你不能使用非捕获组 - “”/(.*)(\bIf(?:I | you)want \ b)(。*)/ iu“' –
不确定你的意思。问题出现在preg_replace中,它将三个括号内的查询替换为$ 1,$ 2和$ 3。如果你添加另一个支架*有时*,那么它显然不能正常工作。这就是为什么我需要这样做可能没有括号......或者必须有其他方式。 – Hasen
你想要从字符串的开始到匹配,然后是匹配,然后是匹配后的文本?你期望一个字符串中的单个匹配吗? –