问题描述
基本上,我想在句子中替换某些单词(例如,单词"tree"和"pizza").限制:当应替换的单词在双引号之间时,不应执行替换.
Basically I want to replace certain words (e.g. the word "tree" with the word "pizza") in sentences. Restriction: When the word that should be replaced is between double quotes, the replace should not be performed.
示例:
The tree is green. -> REPLACE tree WITH pizza
"The" tree is "green". -> REPLACE tree WITH pizza
"The tree" is green. -> DONT REPLACE
"The tree is" green. -> DONT REPLACE
The ""tree is green. -> REPLACE tree WITH pizza
是否可以使用正则表达式执行此操作?我会计算单词前双引号的数量,然后检查它是否为奇数或偶数.但这可以在php中使用preg_replace吗?
Is it possible to do this with regular expressions? I would count the number of double quotes before the word and check if it is odd or even. But is this possible using preg_replace in php?
谢谢!
//
此刻,我的代码如下:
preg_replace("/tree/", "pizza", $sentence)
但是这里的问题是用双引号实现逻辑.我尝试过类似的事情:
But the problem here is to implement the logic with the double quotes. I tried things like:
preg_replace("/[^"]tree/", "pizza", $sentence)
但这是行不通的,因为它仅检查单词前面是否有双引号.但是,在上面的示例中,此检查失败.导入是我只想用正则表达式解决这个问题.
But this does not work, because it checks only if a double quote is in front of the word. But there are examples above where this check fails.Import is that I want to solve that problem with regex only.
推荐答案
正则表达式不是一种可以满足您每项工作所需的工具.您可以在一定程度上使用正则表达式,但是在嵌套引号中的所有情况下,它都会变得越来越复杂.
Regular expression is not a tool that will do what you need for every job. You can use regular expression for this to a certain extent, but for all cases amongst nested quotes, it continues to get more complicated.
您可以在此处使用负向超前.
$text = preg_replace('/\btree\b(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/i', 'pizza', $text);
请参见 Working demo
正则表达式:
\b the boundary between a word char (\w) and not a word char
tree 'tree'
\b the boundary between a word char (\w) and not a word char
(?! look ahead to see if there is not:
[^"]* any character except: '"' (0 or more times)
" '"'
(?: group, but do not capture (0 or more times)
(?: group, but do not capture (2 times):
[^"]* any character except: '"' (0 or more times)
" '"'
){2} end of grouping
)* end of grouping
[^"]* any character except: '"' (0 or more times)
$ before an optional \n, and the end of the string
) end of look-ahead
另一种选择是使用受控回溯,因为您可以在 php
Another option is to use controlled backtracking since your able to do this in php
$text = preg_replace('/"[^"]*"(*SKIP)(*FAIL)|\btree\b/i', 'pizza', $text);
请参见 Working demo
该想法是跳过引号中的内容.我首先匹配引号,后跟除"
以外的任何字符,再加上引号,然后使子模式失败,并强制正则表达式引擎不要使用带有(*SKIP)
和(*FAIL)
回溯控制动词的其他替代方式重试子字符串.
The idea is to skip content in quotations. I first match the quotation followed by any character except "
followed by a quotation and then make the subpattern fail and force the regular expression engine to not retry the substring with an other alternative with (*SKIP)
and (*FAIL)
backtracking control verbs.
这篇关于如果不在双引号内,则为preg_replace的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!