PHP 中的条件正则表达式似乎不起作用
Conditional regex in PHP doesn't seem to work
执行 regular expression match in PHP using the preg suite,我知道您可以在正则表达式中表示条件语句。
我在网上几乎找不到任何文档,所以我求助于 Jeffrey E.F. Friedl's Mastering Regular Expressions。
在我看来,像 /(?(?<=NUM:)\d+|\w+)/
这样的东西在它前面有 NUM:
时应该匹配一个数字,否则它应该匹配一个单词。
但由于某些奇怪的原因,它总是 returns 正确,匹配数据对我来说也没有意义。谁能给我解释一下这是怎么回事?
我想做的是:
preg_replace('/creat(?:e|ing)/i', 'make', $input)
but only when '/creat(?:e|ing)/i' is not surrounded by quotes.
实际上,我需要的输入输出序列是:
- 输入:创建一件白衬衫。
输出:做一件白衬衫。
- 输入: "create a white shirt."
输出: "create a white shirt"
- 输入:你好创造一些好的代码。
输出:你好写一些好的代码。
- 输入:"hello""make some"好"code."
输出:"hello""make some"好"code."
谢谢大家!
编辑:我想做这样的事情:如果有一个开引号,在这种情况下,确保它在匹配关键字 create
之前有一个结束对.希望这是有道理的并且是可能的。
您不需要任何条件结构来跳过引号内的内容。有两种方法。
使用替代分支匹配带引号的子字符串并使用 (*SKIP)(*FAIL)
动词:
preg_replace('/"[^"]*"(*SKIP)(*F)|creat(?:e|ing)/i', 'make', $input)
图案详情:
"[^"]*"
- 匹配 "
,然后是 "
以外的 0+ 个字符,然后是 "
(*SKIP)(*F)
- 使正则表达式引擎丢弃当前匹配的文本并从当前索引 开始
|
- 或...
creat(?:e|ing)
- 匹配 create
或 creating
.
见demo
另一种方法是仅使用捕获并使用 preg_replace_callback
,您可以在其中检查组是否匹配(并适当地建立替换逻辑):
preg_replace_callback('/("[^"]*")|creat(?:e|ing)/i', function($m) {
return !empty($m[1]) ? $m[1] : 'make';
}, $input)
图案详情:
("[^"]*")
- 第 1 组(稍后可以从替换模式中用 </code> 引用) - 双引号字符串 </li>
<li><code>|
- 或
creat(?:e|ing)
- 匹配 create
或 creating
.
请注意,"[^"]*"
是一个示例正则表达式,如果您需要将 C 字符串与转义序列匹配,您应该至少使用 "[^"\\]*(?:\\.[^"\\]*)*"
(在代码中)。
执行 regular expression match in PHP using the preg suite,我知道您可以在正则表达式中表示条件语句。
我在网上几乎找不到任何文档,所以我求助于 Jeffrey E.F. Friedl's Mastering Regular Expressions。
在我看来,像 /(?(?<=NUM:)\d+|\w+)/
这样的东西在它前面有 NUM:
时应该匹配一个数字,否则它应该匹配一个单词。
但由于某些奇怪的原因,它总是 returns 正确,匹配数据对我来说也没有意义。谁能给我解释一下这是怎么回事?
我想做的是:
preg_replace('/creat(?:e|ing)/i', 'make', $input)
but only when '/creat(?:e|ing)/i' is not surrounded by quotes.
实际上,我需要的输入输出序列是:
- 输入:创建一件白衬衫。
输出:做一件白衬衫。
- 输入: "create a white shirt."
输出: "create a white shirt"
- 输入:你好创造一些好的代码。
输出:你好写一些好的代码。
- 输入:"hello""make some"好"code."
输出:"hello""make some"好"code."
谢谢大家!
编辑:我想做这样的事情:如果有一个开引号,在这种情况下,确保它在匹配关键字 create
之前有一个结束对.希望这是有道理的并且是可能的。
您不需要任何条件结构来跳过引号内的内容。有两种方法。
使用替代分支匹配带引号的子字符串并使用 (*SKIP)(*FAIL)
动词:
preg_replace('/"[^"]*"(*SKIP)(*F)|creat(?:e|ing)/i', 'make', $input)
图案详情:
"[^"]*"
- 匹配"
,然后是"
以外的 0+ 个字符,然后是"
(*SKIP)(*F)
- 使正则表达式引擎丢弃当前匹配的文本并从当前索引 开始
|
- 或...creat(?:e|ing)
- 匹配create
或creating
.
见demo
另一种方法是仅使用捕获并使用 preg_replace_callback
,您可以在其中检查组是否匹配(并适当地建立替换逻辑):
preg_replace_callback('/("[^"]*")|creat(?:e|ing)/i', function($m) {
return !empty($m[1]) ? $m[1] : 'make';
}, $input)
图案详情:
("[^"]*")
- 第 1 组(稍后可以从替换模式中用</code> 引用) - 双引号字符串 </li> <li><code>|
- 或creat(?:e|ing)
- 匹配create
或creating
.
请注意,"[^"]*"
是一个示例正则表达式,如果您需要将 C 字符串与转义序列匹配,您应该至少使用 "[^"\\]*(?:\\.[^"\\]*)*"
(在代码中)。