【问题标题】:Regular expression with if condition带有 if 条件的正则表达式
【发布时间】:2016-08-30 08:56:39
【问题描述】:

我是正则表达式的新手。我正在尝试构建一个正则表达式 前三个字符必须是字母,然后字符串的其余部分可以是任何字符。如果前三个字符之后的字符串部分包含 & 则这部分应该以 " 开头和结尾。

我能够构造^[a-z]{3},但卡在条件语句中。

例如abcENTabc"E&T" 是有效字符串,但abcE&T 不是。

这可以在一个表达式中完成吗?

【问题讨论】:

  • 您可以交替执行此操作。类似^[a-z]{3}([^&]*|".*")$

标签: regex


【解决方案1】:

在大多数正则表达式风格中,您可以使用简单的前瞻来确保某些文本是否存在于当前位置右侧的某个位置,并使用交替运算符| 可以检查替代项。

所以,我们基本上有 2 个选择:在前 3 个字母之后的字符串中某处有一个 &,或者没有。因此,我们可以使用

^[A-Za-z]{3}(?:(?=.*&)".*"|(?!.*&).*)$

regex demo

详情

  • ^ - 字符串开头
  • [A-Za-z]{3} - 3 个字母
  • (?:(?=.*&)".*"|(?!.*&).*) - 两种选择中的任何一种:
    • (?=.*&)".*" - 如果字符串 ((?=.*&)) 中某处有 & 匹配 ",然后是任何 0+ 字符,然后是 "
    • | - 或
    • (?!.*&).* - 如果字符串中没有 & ((?!.*&)),只需匹配任何 0+ 字符直到...
  • $ - 字符串结束。

在 PCRE、.NET 或其他一些正则表达式风格中,您可以访问 条件构造。这是PCRE demo

^[A-Za-z]{3}(?(?=.*&)".*"|.*)$
            ^^^^^^^^^^^^^^^^^

(?(?=.*&)".*"|.*) 表示:

  • (?(?=.*&) - 如果在任何 0+ 个字符后有 &...
  • ".*" - 匹配 "anything here"-like 字符串
  • | - 或者,如果没有 &
  • .* - 匹配当前位置的任何 0+ 个字符(即前 3 个字母之后)。

【讨论】:

【解决方案2】:

条件语句可以与 | 一起使用和组,但它可能会很复杂。

^[a-z]{3}([^&]*$|".*"$)

您可能会考虑对这个任务使用普通的旧字符串操作,它可能会很简单

【讨论】:

    【解决方案3】:

    是的,这是可能的,这不是真正的 if,但在您的情况下,您可以使用正则表达式捕获组进行“或”。你的正则表达式看起来像这样:

    \d{3}(\".*\"|[^&]*)
    

    附:这是一个测试和学习这些东西的好网站: https://regex101.com/

    【讨论】:

      【解决方案4】:

      正则表达式不一定支持 'if' 中的条件,为了在一般情况下实现这一点,您必须将条件声明为替代条件。 (但请参阅 Wiktor 的评论,根据您的正则表达式引擎,可能会有可用的条件。)

      对于一个相对基本的解决方案,您可以尝试以下方法:

      ^[a-z]{3}([^&]*|\..*\.)$
      

      上面写着“在四个字母之后,应该有一个任意长度的字符串,没有与号 (&) 或一个以句号 (.) 开头和结尾的字符串。

      【讨论】:

      • Wiktor:有趣的扩展。如果您的正则表达式引擎支持它,值得一看。
      • 三个字母后应该有一个任意长度的字符串,但即使三个字母后没有字符串也可以。请问你能帮忙吗?
      • 任意长度的字符串不包括长度为0的字符串?
      【解决方案5】:

      表达式本身将取决于您将使用的正则表达式解析器。如果你使用 Python、shell、vim、boost 等,同一个符号可能有不同的含义。

      我会尝试以下方法:

      $ echo 'abc"&def"' | grep -E "^[a-zA-Z]{3}(\".*\&.*\"|[^&]*)"
      abc"&def"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多