【问题标题】:Matching an optional substring in a regex匹配正则表达式中的可选子字符串
【发布时间】:2021-11-26 09:40:16
【问题描述】:

我正在开发一种算法来解析一系列短字符串中的数字。这些字符串有些规则,但有一些不同的一般形式和几个例外。我正在尝试构建一组处理各种形式和异常的正则表达式;我会一个接一个地应用它们,看看我是否得到匹配。

其中一种形式如下所示:

X (Y) Z

地点:

  • X 是我要捕获的数字。
  • Z 是静态的预定义文本。这基本上是我确定这种特定形式是否适用的方式。
  • Y 是一个长度和内容未知的字符串,用括号括起来。

另外:Y 是可选的;它并不总是出现在带有ZX 的字符串中。所以,我希望能够从所有这些字符串中提取数字:

  • 10 Z
  • 20 (foo) Z
  • 30 (bar) Z

现在,我有一个正则表达式可以捕获第一个:

([0-9]+) +Z

我的问题是我不知道如何构造一个匹配一系列字符的正则表达式,当且仅当它们被括在括号中时。这可以在单个正则表达式中完成吗?

【问题讨论】:

    标签: regex


    【解决方案1】:
    (\d+)\s+(\(.*?\))?\s?Z
    

    注意转义的括号和?(零或一次)量词。您不想捕获的任何组都可以是(?:非捕获组)。

    我同意空格。 \s 是一个更好的选择。我还更改了量词以确保开头有数字。至于换行符,这将取决于上下文:如果文件被逐行解析,那将不是问题。另一种选择是锚定行的开头和结尾(在前面添加^,在末尾添加$)。

    【讨论】:

    • 空间是静态的。将它们替换为 \s+
    • 或将其中一个放在 ( ) 内?
    • 请注意,如果正则表达式使用 .或者如果一行上有多个实例,这应该是非贪婪的: (\d*) ((.*?))? Z
    • 感谢?: 非捕获组的建议,这很容易。
    【解决方案2】:

    这应该可以工作:

    ^\d+\s?(\([^\)]+\)\s?)?Z$
    

    虽然还没有测试过,但让我给你分解一下,所以如果还有任何错误,它们应该很容易找到:

    首先开始:

    ^ = beginning of string
    \d+ = one or more decimal characters
    \s? = one optional whitespace
    

    然后这部分:

    (\([^\)]+\)\s?)?
    

    其实是:

    (.............)?
    

    这使得以下内容是可选的,只有当它完全存在时

    \([^\)]+\)\s?
    
    \( = an opening bracket
    [^\)]+ = a series of at least one character that is not a closing bracket
    \) = followed by a closing bracket
    \s? = followed by one optional whitespace
    

    而结尾是由

    Z$
    

    在哪里

    Z = your constant string
    $ = the end of the string
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      ([0-9]+) (\([^)]+\))? Z
      

      但是,这不适用于 Y 的嵌套括号。嵌套需要递归,它不再是严格规则的(但与上下文无关)。现代正则表达式引擎仍然可以处理它,尽管有一些困难(反向引用)。

      【讨论】:

      • 幸运的是,我认为我不需要处理嵌套的括号。
      【解决方案4】:

      试试这个:

      X (\(Y\))? Z
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多