【问题标题】:RegEx different substitutions based on groups?RegEx 基于组的不同替换?
【发布时间】:2018-02-12 07:22:42
【问题描述】:

所以我在正则表达式方面比较n00bish,并且做了一些练习。

我正在玩一个简单的“deobfucator”,它只寻找[dot](dot)[at](at)。不区分大小写,并且在匹配之前或之后有或没有任何数量的空格。

这是通常的:someemail [AT] domain (dot) com 类型的东西。我显然想把它变成someemail@domain.com

我想出的正则表达式可以很好地匹配,但现在我想根据匹配替换为 .@

即 我希望匹配“点”组的组将其替换为文字.,并将匹配“at”组的组替换为文字@

我知道我可以只编写 2 个不同(几乎相同)的 RegEx 并运行它们,但为了教育起见,我想看看我是否可以在一个 RegEx 中完成所有操作?

这是我想出的正则表达式(可能不是最小的,我也有兴趣看到):

+(\[|\()(dot)(\)|\]) +| +(\[|\()(at)(\)|\]) +

注意:在每个+ 之前都有一个空格,用于匹配空格。

我正在寻找的是什么我会用什么来正确地进行替换?

更新:对不起,忘记添加我正在使用的语言。在这种情况下,我使用了一个剪贴板实用程序,它可以在其输入上运行 RegEx(无论复制到剪贴板的内容),并且它使用的引擎是 C#/VB.NET。这个小项目的最终目标是能够复制“混淆”的电子邮件地址或 URL,并在其上运行 RegEx,以便将其设置在剪贴板上的“未混淆”状态。

也就是说,我确实倾向于在许多不同的语言上使用 RegEx,因此在语言之间转换它们通常不是问题。

【问题讨论】:

    标签: c# .net regex vb.net


    【解决方案1】:

    .NET 正则表达式不支持条件替换模式。

    为了教育起见,我正在尝试看看我是否可以在一个 RegEx 中完成所有操作?

    还有其他正则表达式引擎允许在单个正则表达式替换操作中使用conditional replacement patterns 进行条件替换逻辑。

    有 3 个引擎支持这种类型的替换:JGsoft V2、Boost 和 PCRE2。

    要在 Boost 中使用条件,您需要将 regex_constants::format_all 传递给 regex_replace。要让他们在 PCRE2 中工作,您需要将 PCRE2_SUBSTITUTE_EXTENDED 传递给 pcre2_substitute

    在 PCRE2 中:

    ${1:+matched:unmatched} 其中 1 是 1 到 99 之间的数字,引用编号的捕获组。如果您的正则表达式包含命名的捕获组,那么您可以通过它们的名称在条件中引用它们:${name:+matched:unmatched}

    如果您想在匹配部分使用文字冒号,则需要使用反斜杠对其进行转义。如果您想在条件中的任何位置使用文字结束大括号,那么您也需要使用反斜杠对其进行转义。除了以条件开头的:+ 之外,加号没有特殊含义,因此不需要转义。

    另外,请参阅The Boost-Specific Format Sequences

    format_all 标志指定为regex_replace() 时,识别的转义序列与上面format_perl 的转义序列相同。此外,还可以识别以下形式的条件表达式:

    ?Ntrue-expression:false-expression

    其中N 是代表子匹配的十进制数字。如果对应的子匹配参与了完整匹配,则替换为真表达式。否则为假表达式。在这种模式下,您可以使用parens () 进行分组。如果你想要一个文字括号,你必须将它转义为\(

    在 Boost 替换模式中,文字 () 必须转义。

    JGsoft V2 替换字符串条件的语法与 C++ Boost 库中的语法相同。

    因此,您的正则表达式可以收缩为( +)[[(](?:(dot)|(at))[])]( +)

    • ( +) - 第 1 组:一个或多个空格
    • [[(] - [(
    • (?:(dot)|(at)) - (第 2 组)dot 子字符串或(第 3 组)at 子字符串
    • [])] - )]
    • ( +) - 第 4 组:一个或多个空格

    并替换为$1(?{3}.:@)$4:

    • $1 - 第 1 组值,
    • (?{3}.:@) - 如果第 3 组匹配,则替换为 .,否则替换为 @
    • $4 - 第 4 组值。

    这在 Notepad++ 中可用:

    【讨论】:

    • 哇,没听说过这些条件句,谢谢分享!
    • @J.ScottElblein:.NET 正则表达式不支持条件替换模式。如果您可以访问代码,那应该没问题。否则,你不能使用没有的东西,对不起。
    【解决方案2】:

    如果您使用 Java,请尝试 String 类中的 replaceAll 方法。

    最后你需要用空格对其进行标准化:
    - 纯 Java - String after = before.trim().replaceAll("\\s+", " ");
    - 纯 Java - String after = before.replaceAll("\\s{2,}", " ").trim();
    - Apache commons lang3 - String after = StringUtils.normalizeSpace(String str);
    - ...

    【讨论】:

    • 谢谢Tooraj。我在这里使用 VB/C#,所以最终我将使用几乎相同版本的 .ReplaceAll。 =)
    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2020-09-01
    • 2021-08-24
    相关资源
    最近更新 更多