在正则表达式匹配中替换字符

5

我希望匹配任何文本中的某些行,并在该匹配内,将某个字符替换为它出现的次数一样多。

示例文本:

Any text and "much" "more" of it. Don't replace quotes here
CatchThis( no quotes here, "any more text" , "and so on and so forth...")
catchthat("some other text" , "or less")
some text in "between"
CatchAnything ( "even more" , "and more", no quotes there, "wall of text")
more ("text"""") and quotes after...

现在,我想要用另一个符号(比如 #)来替换括号内部的每个引号。

期望的输出:

Any text and "much" "more" of it. Don't replace quotes here
CatchThis( no quotes here, #any more text# , #and so on and so forth...#)
catchthat(#some other text# , #or less#)
some text in "between"
CatchAnything ( #even more# , #and more#, no quotes there, #wall of text# )
more ("text"""") and quotes after...

匹配这些行很容易。这是我的模式:

(?i)Catch(?:This|That|Anything)[ \t]*\(.+\)

很遗憾,我不知道如何匹配每一个引号并替换它...

2个回答

6

在IT技术中,常见的匹配两个不同定界符内所有模式出现次数的方法是使用基于\G锚点的正则表达式。

(?i)(?:\G(?!\A)|Catch(?:This|That|Anything)\s*\()[^()"]*\K"

请查看正则表达式演示解释:
  • (?i) - 忽略大小写修饰符
  • (?: - 一个非捕获组匹配两个备选项
    • \G(?!\A) - 正好在前面的匹配成功后字符串的位置(因为\G也可以匹配字符串的开头,所以(?!\A)很有必要来排除这种可能性)
    • | - 或者
    • Catch(?:This|That|Anything) - Catch后面跟着ThisThatAnything
    • \s* - 0个或多个空格
    • \( - 一个括号符号
  • ) - 非捕获组结束
  • [^()"]* - 任何0个或多个字符,但不包括()"
  • \K - 匹配重置操作符
  • " - 双引号。

  • 1
    非常好!正合医生所需。完美地运作着……感谢你提供的解释! - TheFriesel
    1
    如果您需要在多个字符分隔符之间匹配多个标记,我建议使用"tempered greedy token"而不是否定字符类(这里使用[^()"]*)。 - Wiktor Stribiżew
    谢谢你提醒我!我会去查一下,不过首先,我得完全理解你的模式 ;) - TheFriesel
    1
    请告诉我哪些部分让您感到困惑,我会更新答案。 - Wiktor Stribiżew
    非常感谢你,Wiktor!我明白了组成部分,只是整个模式还没有理解透彻。目前,我认为自己无法想出这样的解决方案,但给我一些时间吧 ;) - TheFriesel

    0

    你真的需要在正则表达式内部进行替换吗?如果你的正则表达式找到了你想要的内容,你可以在找到的字符串上进行字符替换。


    这就是我现在正在做的事情:获取匹配项数组,替换引号并将修改后的匹配项注入回原始文本。这相当复杂,我认为直接在匹配项内部进行替换更加优雅,也可能更快... - TheFriesel

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接