问题描述
使用 preg 套件在 PHP 中执行 正则表达式匹配,我明白您可以在正则表达式中表示条件语句.
Performing a regular expression match in PHP using the preg suite, I understand that you can represent a conditional statement right within the regex.
我在网上几乎找不到任何文档,所以我求助于 Jeffrey E.F. Friedl 的掌握正则表达式.
I could hardly find any documentation online so I turned to Jeffrey E.F. Friedl's Mastering Regular Expressions.
在我看来,像 /(?(?<=NUM:)\d+|\w+)/
之类的东西应该与 NUM 前面的数字匹配:
否则它应该匹配一个单词.
The way I see it, something like /(?(?<=NUM:)\d+|\w+)/
should match a digit when it is preceded by NUM:
otherwise it should match a word.
但出于某种奇怪的原因,它总是返回 true 并且匹配数据对我来说也没有意义.有人可以向我解释这是怎么回事吗?
But for some weird reason it always returns true and the match data doesn't make sense to me either. Can someone explain to me what's going on?
我想做的是:
preg_replace('/creat(?:e|ing)/i', 'make', $input)
but only when '/creat(?:e|ing)/i' is not surrounded by quotes.
实际上,我需要的输入-输出序列是:
in action, the input-output sequence I need is:
- 输入:创建一件白衬衫.
- input: create a white shirt.
输出:做一件白衬衫.
- 输入:制作一件白衬衫."
- input: "create a white shirt."
输出:创建一件白衬衫"
- 输入:你好,创建一些好的代码.
- input: hello create some good code.
输出:你好,编写一些好的代码.
output: hello make some good code.
- 输入:你好"制作一些"好的代码".
- input: "hello" "make some" good "code."
输出:你好"制作一些"好的代码".
output: "hello" "make some" good "code."
谢谢大家!
编辑:我想做一些类似的事情:如果有一个开引号,在这种情况下,在匹配关键字 create
之前,确保它有一个结束对.希望这是有道理的,也是可能的.
Edit: I want to do something like: if there is an opening quote, make sure it has a closing pair before matching the keyword create
in this case. Hope that makes sense and is possible.
推荐答案
您不需要任何条件结构来跳过引号内的内容.有两种方式.
You do not need any conditional constructs to skip what is inside quotes. There are two ways.
使用与带引号的子字符串匹配的替代分支并使用 (*SKIP)(*FAIL)
动词:
Use an alternative branch matching a quoted substring and use (*SKIP)(*FAIL)
verbs:
preg_replace('/"[^"]*"(*SKIP)(*F)|creat(?:e|ing)/i', 'make', $input)
模式详情:
"[^"]*"
- 匹配"
,然后是除"
之外的 0+ 个字符,然后是"
(*SKIP)(*F)
- 使正则表达式引擎丢弃当前匹配的文本并从当前索引开始|
- 或...creat(?:e|ing)
- 匹配create
或creating
.
"[^"]*"
- matches"
, then 0+ characters other than"
and then a"
(*SKIP)(*F)
- make the regex engine discard the currently matched text and proceed from the current index|
- or...creat(?:e|ing)
- matchcreate
orcreating
.
参见演示
另一种方法是仅使用捕获和使用 preg_replace_callback
,您可以在其中检查组是否匹配(并适当地建立替换逻辑):
Another way is mere using capturing and using preg_replace_callback
where you can check if a group was matched (and base the replacement logic appropriately):
preg_replace_callback('/("[^"]*")|creat(?:e|ing)/i', function($m) {
return !empty($m[1]) ? $m[1] : 'make';
}, $input)
查看 IDEONE 演示
模式详情:
("[^"]*")
- 第 1 组(稍后可以使用替换模式中的$1
引用) - 双引号字符串|
- 或creat(?:e|ing)
- 匹配create
或creating
.
("[^"]*")
- Group 1 (can be later referenced with$1
from the replacement pattern) - a double quoted string|
- orcreat(?:e|ing)
- matchcreate
orcreating
.
注意"[^"]*"
是一个示例正则表达式,如果你需要匹配带有转义序列的C字符串,你至少应该使用"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"
(在代码中).
Note that "[^"]*"
is a sample regex, if you need to match C strings with escaped sequences, you should use at least "[^"\\\\]*(?:\\\\.[^"\\\\]*)*"
(in the code).
这篇关于PHP 中的条件正则表达式似乎不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!