2009-11-18 63 views
0

我已经建立一个复杂的(对我来说)正则表达式解析一些文件名,它广泛适用,除了那里有更多的括号内的情况。正则表达式:使用周围括号作为分隔符,而忽略任何括号内

(?'field'F[0-9]{1,4})(?'term'\(.*?\))(?'operator'_(OR|NOT|AND)_)? 

在下面的例子,我需要的意见后,得到群体,但在第三个例子,我得到((brackets)而不是((brackets)are valid)

对于我的生活,我不能工作,如何把它扩大到搜索最终支架。

C:\Temp\[DB_3][DT_2][F30(green)].vsl // F30 (green) 
C:\Temp\[DB_3][DT_2][F21(red)_OR_F21(blue)_NOT_F21(pink)].vsl // F21 (red) _OR_ OR 
C:\Temp\[DB_3][DT_2][F21((brackets)are valid)].vsl // F21 ((brackets)are valid) 
C:\Temp\[DB_3][DT_2][F21(any old brackets)))))are valid)].vsl // F21 (any old brackets)))))are valid) 
C:\Temp\[DB_3][DT_2][F21(brackets))))))_OR_F21(blue)].vsl // F21 (brackets)))))) _OR_ OR 

感谢


UPDATE:我使用RegExr实验,然后在C#中实现这样的:

Regex r = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace); 

foreach(Match m in r.Matches(foo)) 
{ 
    //etc 
} 

更新2:我不需要匹配括号。在一组括号内可以是任何数据,我只需要它以外括号终止。


UPDATE 3:

的另一种尝试,这可与额外的括号(实施例3和4),但仍无法打出额外术语(实施例5),但不幸的是包括在终止]群组。我怎样才能让它搜索(但不包括))_)]作为分隔符,但只包括括号?

(?'field'F[0-9]{1,4})(?'term'\(.*?\)[\]])(?'operator'_(OR|NOT|AND)_)? 

最后更新:我已经决定了它不值得在试图解析这个愚蠢格式的努力,所以我打算抛弃的支持,并做一些更高效地使用我的时间。谢谢大家的帮助,我现在已经看到了灯光!

+0

从标题中不太清楚您是否a)要求匹配外部括号的帮助,或者b)尝试避免匹配外部括号。 – pavium 2009-11-18 11:58:32

+0

我已更新标题,希望更有意义 – 2009-11-18 12:02:37

回答

2

匹配正则表达式的与嵌套括号是一个)不可能*,或B)导致一个正则表达式是难以维护。

如果你只是想第一(匹配直到最后)(不检查,如果opening-和闭括号正确地匹配),那么就.*?后删除?

*取决于你所使用的正则表达式的味道。

+0

我不需要匹配内部数据,只需使用外部括号作为终结符。 我正确地认为你的意思是它应该这样? (?'field'F [0-9] {1,4})(?'term'\(。* \))(?'operator'_(OR | NOT | AND)_)?'解决问题,我的第三个例子,但打破了在第二个例子中的组(即组2然后捕获'(红色)_OR_F21(蓝色)_NOT_F21(粉红色)') – 2009-11-18 11:46:39

+0

在阅读您的更新后,我必须承认,它不清楚对我来说,匹配你在评论中指出的子字符串的规则是什么。似乎有时候你想匹配括号('((括号)是有效的'),有时你不会('(括号))))))')。 – 2009-11-18 12:27:30

+0

请注意,标题*“使用周围的括号作为分隔符而忽略任何内部括号”*有点令人误解。它表明'((括号)'是一个有效的匹配。) – 2009-11-18 12:35:55

2

嗯,这通常是不可能的大多数正则表达式引擎。尽管可以在Perl:

PerlMonks

通过使用递归的正则表达式:

use strict; 
use warnings; 

my $textInner = 
    '(outer(inner(most "this (shouldn\'t match)" inner)))'; 
my $innerRe; 
my $idx=0; 
my(@match); 

$innerRe = qr/ 
       \(
       (
        (?: 
         [^()"]+ 
        | 
         "[^"]*" 
        | 
         (??{$innerRe}) 
        )* 
       ) 
       \)(?{$match[$idx++]=$1;}) 
      /sx; 

$textInner =~ /^$innerRe/g; 

print "inner: $match[0]\n"; 

也有可能做到这一点在提供的大多数正则表达式引擎要它做一个固定的深度的支架嵌套。前段时间我在java中写了一些东西,它会构造一个正则表达式,可以匹配6个深度的括号。

这是我生产的正则表达式的Java功能:

public static String generateParensMatchStr(int depth, char openParen, char closeParen) 
{ 
    if (depth == 0) 
     return ".*?"; 
    else 
     return "(?:\\" + openParen + generateParensMatchStr(depth - 1, openParen, closeParen) + "\\" +closeParen + "|.*?)+?"; 
} 
1
re.findall("((?:F[0-9]{1,4}\(.*\))(?:_(?:OR|NOT|AND)_)?)+?",YOURTEXT) 

GOTS

['F30(green)', 'F21(red)_OR_F21(blue)_NOT_F21(pink)', 'F21((brackets)are valid)', 'F21(any old brackets)))))are valid)', 'F21(brackets))))))_OR_F21(blue)'] 
在Python

,你有什么感想?

1

试试这个

/(F[0-9]{1,4})(\([^_\]]+\))(?:_(OR|NOT|AND)_)?/

用PHP进行测试,似乎给了预期的结果(只要圆括号中的字符串不包含_])。

2

这里是我的另一项测试结果蟒蛇

x="""C:\Temp\[DB_3][DT_2][F30(green)].vsl // F30 (green) 
C:\Temp\[DB_3][DT_2][F21(red)_OR_F21(blue)_NOT_F21(pink)].vsl // F21 (red) _OR_ OR 
C:\Temp\[DB_3][DT_2][F21((brackets)are valid)].vsl // F21 ((brackets)are valid) 
C:\Temp\[DB_3][DT_2][F21(any old brackets)))))are valid)].vsl // F21 (any old brackets)))))are valid) 
C:\Temp\[DB_3][DT_2][F21(brackets))))))_OR_F21(blue)].vsl // F21 (brackets)))))) _OR_ OR""" 
x=re.sub("//.*","",x) 
x=re.sub("(_(OR|NOT|AND)_).*?]"," \\1 \\2]",x) 
x=re.findall("(?:F[0-9]{1,4}\(.*\).*(?=]))",x) 
for x in x:print x 

这给

F30(green) 
F21(red) _OR_ OR 
F21((brackets)are valid) 
F21(any old brackets)))))are valid) 
F21(brackets)))))) _OR_ OR 

那将满足您预期的结果?

相关问题