php - 如何做只匹配特定条件的preg_replace?

标签 php regex

我正在努力编写一个 preg_replace 命令来实现我的需要。

基本上我有以下数组(所有项目都遵循这四种模式之一):

$array = array('Dogs/Cats', 'Dogs/Cats/Mice', 'ANIMALS/SPECIES Dogs/Cats/Mice', '(Animals/Species) Dogs/Cats/Mice' );

我需要能够得到以下结果:

Dogs/Cats = Dogs or Cats

Dogs/Cats/Mice = Dogs or Cats or Mice

ANIMALS/SPECIES Dogs/Cats/Mice = ANIMALS/SPECIES Dogs or Cats or Mice

(Animals/Species) Dogs/Cats/Mice = (Animals/Species) Dogs or Cats or Mice

所以基本上替换任何不是大写字母或括号的斜线。

我开始掌握它,但仍需要一些指导:

preg_replace('/(\(.*\)|[A-Z]\W[A-Z])[\W\s\/]/', '$1 or', $array);

如您所见,它识别出第一个模式,但我不知道从那里去哪里

谢谢!

最佳答案

您可以使用 \G anchor 断言上一次匹配的位置,并使用 \K 忘记匹配的内容以仅匹配 /.

您可以选择在开头匹配 ANIMALS/SPECIES(Animals/Species)

(?:^(?:\(\w+/\w+\)\h+|[A-Z]+/[A-Z]+\h+)?|\G(?!^))\w+\K/

解释

  • (?: 非捕获组
    • ^ 断言字符串开始
    • (?: 非捕获组,匹配
      • \(\w+/\w+\)\h+(....) 1+ 个单词字符之间匹配 /在以 1+ 个水平空白字符结尾之间
      • | 或者
      • [A-Z]+/[A-Z]+\h+ 匹配 1+ 次 [A-Z], / 并再次匹配 1+ 次 [A-Z]
    • )? 关闭非捕获组并使其可选
    • |
    • \G(?!^) 断言上一场比赛的位置
  • )\w+ 关闭非捕获组并匹配一个单词char 1+次
  • \K/ 忘记匹配的是什么,匹配一个/

Regex demo | Php demo

在替换中使用一个空格,和一个空格

例如

$array = array('Dogs/Cats', 'Dogs/Cats/Mice', 'ANIMALS/SPECIES Dogs/Cats/Mice', '(Animals/Species) Dogs/Cats/Mice');
$re = '~(?:^(?:\(\w+/\w+\)\h+|[A-Z]+/[A-Z]+\h+)?|\G(?!^))\w+\K/~';
$array = preg_replace($re, " or ", $array);
print_r($array);

结果:

Array
(
    [0] => Dogs or Cats
    [1] => Dogs or Cats or Mice
    [2] => ANIMALS/SPECIES Dogs or Cats or Mice
    [3] => (Animals/Species) Dogs or Cats or Mice
)

关于php - 如何做只匹配特定条件的preg_replace?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56754606/

相关文章:

php - guzzlephp(或 php-ga-measurement-protocol)中的异步请求

javascript - 无法获取从 PHP 到 $.ajax 的 JSON 回显

php - Magento 选择查询未使用 foreach 循环正确循环

regex - 匹配/之后的最后一个词

javascript - 有效和无效电子邮件地址的正则表达式

php - 移除顶层数组并将子数组合并为一个

php - 将 PHP 对象图序列化/反序列化为 JSON

Python正则表达式从字符串中删除电子邮件

regex - 如何将正则表达式替换中捕获的模式转换为大写?

c++ - 将正则表达式与组相交,如何导出分组位的交集?