【问题标题】:Regex expression to replace a word between two differents words in a string正则表达式替换字符串中两个不同单词之间的单词
【发布时间】:2019-02-24 10:54:27
【问题描述】:

我想使用正则表达式将两个单词 MNOXYZ 之间的单词 ABC 替换为 '',但不是出现不在 MNO 之间的单词 ABCXYZ

例如,给定以下字符串:

Lorem ABC ipsum ABC bla MNO bla ipsum ABC asfg 123 hello ABC dd ABC XYZ hello ABC

预期的结果是:

Lorem ABC ipsum ABC bla MNO bla ipsum asfg 123 hello dd XYZ hello ABC

所以唯一被替换的ABCMNOXYZ 之间的三个。

我在 PHP 中的 preg_replace 中尝试了一些正则表达式,但没有成功。

比如这个我不知道怎么不匹配除了ABC

/(?<=MNO)(.*)ABC(.*)(?=XYZ)/g

Here's a test link.

我希望在这种情况下使用正则表达式和preg_replace

有什么想法吗? 谢谢

【问题讨论】:

  • 是否必须使用preg_replace 或者也可以使用preg_replace_callback
  • Wiktor, preg_replace_callback 可以用来。
  • MNO 和 XYZ 可以多次出现吗?
  • Wiktor,为它可能会阐明的问题添加了一个示例。
  • Rarst,在这种情况下只有一次,但我不介意

标签: php regex preg-replace


【解决方案1】:

你可以使用preg_replace_callback:

$s = preg_replace_callback('~(MNO)(.*?)(XYZ)~s', function($m) {
    return $m[1] . str_replace('ABC', 'XXX', $m[2]) . $m[3];
}, $s);

或者,通过环视,使匿名函数内部的代码更精简:

$s = preg_replace_callback('~(?<=MNO).*?(?=XYZ)~s', function($m) {
    return str_replace('ABC', 'XXX', $m[0]);
}, $s);

PHP demo

这里,(MNO)(.*?)(XYZ) 匹配并捕获 MNO,所有在 MNOXYZ 之间 然后将XYZ 分成三组,在匿名函数内部,所有ABCs 仅在第二组中被替换。请注意,正则表达式末尾的 s 标志也是使 . 匹配换行符所必需的。

在第二个示例中,(?&lt;=MNO) 是一个不消耗文本的正向后视,并且要求 MNO 立即出现在当前位置的左侧,(?=XYZ) 是一个正向前瞻,需要 XYZ立即出现在当前位置的右侧,也不消耗文本,因此这里不需要组。

preg_replace 更难:

preg_replace('~(?:\G(?!\A)|MNO)(?:(?!MNO).)*?\KABC(?=(?:(?!MNO).)*?XYZ)~s', 'XXX', $s)

请参阅regex demo

详情

  • (?:\G(?!\A)|MNO) - 上一场比赛结束或MNO
  • (?:(?!MNO).)*? - 任何 1 个字符,0 次或多次出现,尽可能少,不会启动 MNO 字符序列
  • \K - 匹配重置运算符,丢弃匹配缓冲区中的文本
  • ABC - 一个ABC
  • (?=(?:(?!MNO).)*?XYZ) - 紧靠右边,必须有 0+ 个字符,尽可能少,不以 MNO 字符序列开头,后跟 XYZ

【讨论】:

  • 在这种情况下,它适用于不止一次出现的 MNO 和 XZY。现在没有必要,但如果有必要我会记住的。非常感谢。
【解决方案2】:

如果句子中只出现一次MNOXYZ,这将起作用。

试试这个正则表达式:

ABC(?!.*MNO)(?=.*XYZ)

用空白字符串替换每个匹配项

Click for Demo

说明:

  • ABC - 匹配 ABC
  • (?!.*MNO) - 否定前瞻,以确保当前匹配后没有在字符串后面的某处出现MNO
  • (?=.*XYZ) - 积极的前瞻,以确保当前匹配后跟在字符串后面某处的 XYZ

代码(RESULT)

$re = '/ABC(?!.*MNO)(?=.*XYZ)/m';
$str = 'Lorem `ABC` ipsum ABC bla MNO bla ipsum ABC asfg 123 hello ABC dd ABC XYZ hello ABC
';
$subst = '';
$result = preg_replace($re, $subst, $str);
echo "The result of the substitution is ".$result;

【讨论】:

  • 完美,正是我需要的。
  • megatxi 我觉得@WiktorStribiżew 提供的解决方案要好很多,应该被接受为解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
相关资源
最近更新 更多