2008-10-27 107 views
29

我正在开发一种算法来解析一系列短字符串中的数字。这些字符串有点规则,但有一些不同的一般形式和几个例外。我试图建立一套正则表达式来处理各种形式和异常;我会一个接一个地申请他们,看看我是否得到一场比赛。匹配正则表达式中的可选子字符串

其中一种形式是这样的:

X (Y) Z 

其中:

  • X是一个数字我想捕捉。
  • Z是静态的,预先定义的文本。这基本上是我如何确定这种特殊形式是否适用。
  • Y是一个未知长度和内容的字符串,由括号包围。

另外:Y是可选的;它并不总是出现在与Z和X.因此,一个字符串,我希望能够从所有这些字符串的提取数量:

  • 10ž
  • 20(FOO)z
  • 30(条)z

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

([0-9]+) +Z 

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

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

这不会与Y的嵌套的括号,工作,:

回答

46
(\d+)\s+(\(.*?\))?\s?Z 

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

我同意这些空格。 \ s是更好的选择。我还改变了量词,以确保在开始时有数字。就换行而言,这取决于上下文:如果文件是逐行分析的,它不会成为问题。另一个选项是锚定行的开始和结束(在前面添加^,在末尾添加$)。

+0

空格是静态的。将它们替换为\ s + – 2008-10-27 20:54:46

2

试试这个:

X (\(Y\))? Z 
7

你可以做到这一点。嵌套需要递归,不再是严格规则的(但是无上下文)。现代正则表达式引擎仍然可以处理它,虽然有一些困难(回参考)。

+1

幸运的是我不认为我需要处理嵌套的parens。 – 2008-10-27 20:51:42

14

这应该工作:

^\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