我目前的模式是:
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";
$ value有时会有一个修饰符,如上例和#34;如果(你|我)想要"但其他模式可能只是"接下来发生的事情"没有修饰语。因此额外的括号会引起问题,但我无法找到另一种方法。
编辑:请注意这里的问题是$ 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
但它并不是特别雄辩!
答案 0 :(得分:0)
您遇到的问题是您不能依赖编号捕获组,因为它们的数量可能会有所不同,因为用户定义的模式部分可能包含任意数量的编号捕获组。
可以通过使用命名捕获组来解决问题。它们唯一的问题是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。
你可以&#34;混淆&#34;组名,以便它们不会与用户定义的模式冲突。或者让用户知道模式中不能使用哪些名称。
注意s
修饰符也会使.
匹配换行符。
上述解决方案将与mid
组的 last 匹配项匹配,因为第一个start
模式是贪婪点模式。如果您的字符串包含多个匹配项,并且您希望mid
组匹配字符串中的第一个匹配项,请将(?<start>.*)
替换为(?<start>.*?)
。否则,您需要确定算法应该是什么样的。
答案 1 :(得分:-1)
只为匹配我或你,这对我有用:
$pattern=("/(.*)(\bIf (?:i|you) want\b)(.*)/iu");
答案 2 :(得分:-3)
试试这个:
pattern=("/(.*)(\bIf [I|you]+ want\b)(.*)/iu");