当前位置: 首页 > 知识库问答 >
问题:

不在双引号内时替换preg_

公冶光亮
2023-03-14

基本上,我想在句子中替换某些单词(例如,单词“tree”和单词“pizza”)。限制:当应替换的单词位于双引号之间时,不应执行替换。

例子:

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是否可能?

谢谢

//编辑:

目前我的代码如下:

preg_replace("/tree/", "pizza", $sentence)

但这里的问题是用双引号实现逻辑。我试过这样的方法:

preg_replace("/[^"]tree/", "pizza", $sentence)

但这不起作用,因为它只检查单词前面是否有双引号。但上面有一些例子表明该检查失败。重要的是我只想用正则表达式解决这个问题。

共有3个答案

左丘弘致
2023-03-14

这一个使用前瞻性匹配

$pattern = '~\btree\b(?=([^"]|("[^"]*"))*$)~im';

$str = '
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';

echo "<pre>".preg_replace($pattern,"pizza",$str)."</pre>";

它查找,如果找到,只匹配它,如果后面跟着字符,这些字符不是双引号[^"]或引用组"[^"]*",直到使用修饰符i(PCRE_CASELESS)和m(PCRE_MULTILINE)。

我不要绿色比萨饼!圣诞快乐:-)

燕钟展
2023-03-14

有一个方便的技巧使用一些隐藏的正则表达式的权力:

~“*?”(*跳过)(*失败)|\b树\b~s

说明:

~                   # start delimiter (we could have used /, #, @ etc...)
"                   # match a double quote
.*?                 # match anything ungreedy until ...
"                   # match a double quote
(*SKIP)(*FAIL)      # make it fail
|                   # or
\btree\b            # match a tree with wordboundaries
~                   # end delimiter
s                   # setting the s modifier to match newlines with dots .

在实际的PHP代码中,您可能希望使用preg_quote()来转义regex字符。这里有一个小片段:

$search = 'tree';
$replace = 'plant';
$input = 'The tree is green.
"The" tree is "green".
"The tree" is green.
"The tree is" green.
The ""tree is green.';

$regex = '~".*?"(*SKIP)(*FAIL)|\b' . preg_quote($search, '~') . '\b~s';
$output = preg_replace($regex, $replace, $input);
echo $output;

在线正则表达式演示

东门修能
2023-03-14

正则表达式并不是一个可以为每项工作做所需的工具。您可以在一定程度上使用正则表达式,但对于嵌套引号中的所有情况,它仍然会变得更加复杂。

你可以在这里使用消极的前瞻。

$text = preg_replace('/\btree\b(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/i', 'pizza', $text);

请参见工作演示

正则表达式:

\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中做到这一点

$text = preg_replace('/"[^"]*"(*SKIP)(*FAIL)|\btree\b/i', 'pizza', $text);

请参见工作演示

这个想法是跳过引文中的内容。我首先匹配引号后面的任何字符,除了"后面跟着引号,然后使子模式失败,并迫使正则表达式引擎不要重试子串与其他替代(*SKIP)(*FAIL)回溯控制谓词。

 类似资料:
  • 本文向大家介绍js 单引号替换成双引号,双引号替换成单引号的实现方法,包括了js 单引号替换成双引号,双引号替换成单引号的实现方法的使用技巧和注意事项,需要的朋友参考一下 1.双引号替换成单引号 2.单引号替换成双引号 以上这篇js 单引号替换成双引号,双引号替换成单引号的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 问题内容: 如何使用PHP 用(我认为其称为单引号)替换(我认为它称为双引号)? 问题答案: 或重新分配

  • 在记事本++6.5.1中,我需要替换引号对中的某些模式。我想将替换保存为宏的一部分,所以所有的替换都需要在一个步骤中进行。 编辑:带引号的字符串中的引号用额外的引号转义,例如“”。但是,假设我已经用一个特殊的字符替换了前面的传球中的这些。因此,解决此问题的regex解决方案不必处理转义引号。

  • 我目前正在使用一个替换脚本来自动修复单引号和双引号。 但是,我找不到一个解决方案来更改嵌套在另一个双引号内的任何地方的双引号 “在'abc'开头和结尾有一些额外的文本” 目前,我只能自动修复这个类型,如果它在其他引号旁边(例如“abc”)使用一个简单的替换脚本 和

  • 问题内容: 我正在读取CSV文件,并且有一些值,例如 将文件读取为并转换后,我将文件内容分割为:。 在迭代字符串时,我得到以下值: 如何将两个双引号替换为像这样的“双”的单双 这是我的代码:- 问题答案: 使用。 http://ideone.com/xPQqL