我正在开发一种算法来解析一系列短字符串中的数字。这些字符串有些规律,但有一些不同的一般形式和几个例外。我正在尝试构建一组处理各种形式和异常的正则表达式;我将一个接一个地应用它们,看看我是否得到了一个匹配。
其中一种形式是这样的:
X (Y) Z
其中:
X
是我要捕捉的数字。 Z
是静态的预定义文本。这基本上是我如何确定这种特殊形式是否适用。Y
是一个长度和内容未知的字符串,用括号括起来。 另外:Y
是可选的;它并不总是出现在包含Z
和X
的字符串中。所以,我希望能够从所有这些字符串中提取数字:
10 Z
20 (foo) Z
30 (bar) Z
现在,我有一个正则表达式将捕获第一个:
([0-9]+) +Z
我的问题是,我不知道如何构造一个匹配一系列字符的正则表达式,当且仅当它们括在括号中时。这可以在一个正则表达式中完成吗?
答案 0 :(得分:50)
(\d+)\s+(\(.*?\))?\s?Z
请注意转义的括号和?
(零或一次)量词。您不想捕获的任何组都可以是(?:
非捕获组)。
我同意这些空间。 \s
是一个更好的选择。我还改变了量词,以确保开头有数字。就换行而言,这将取决于上下文:如果逐行解析文件,则不会出现问题。另一种选择是锚定行的开头和结尾(在前面添加^
,在结尾添加$
。
答案 1 :(得分:17)
这应该有效:
^\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
答案 2 :(得分:7)
你可以这样做:
([0-9]+) (\([^)]+\))? Z
然而,这不适用于Y的嵌套parens。嵌套需要递归,这不再是严格规则的(但不含上下文)。现代正则表达式引擎仍然可以处理它,虽然有一些困难(反向引用)。
答案 3 :(得分:4)
试试这个:
X (\(Y\))? Z
答案 4 :(得分:-1)
如果您需要捕获的只是数字,并且数字出现在字符串的开头,那么您可以简单地使用PHP type juggling快速高效地完成这项艰苦的工作:
$value = "10 Z";
$value = "20 (foo) Z";
$value = "30 (bar) Z";
$value = "Cheese";
$value = " 40 (flat) Z";
$value = "22(456)";
$X = (int)trim($value);
输出:
$ x = 10
$ x = 20
$ x = 30
$ x = 0
$ x = 40
$ x = 22