正则表达式:匹配某些字符之间的单词,但不匹配其他某些字符之间(在.NET中)

时间:2017-03-29 09:55:16

标签: .net regex

我希望匹配括号中的所有单词,包括括号,它们不在简单的引号之间(在.NET中):

"[field1] = 'id1'" -> match "[field1]"
"[field1] = '[field2]'" -> match "[field1]"
"[ field1 ] = '[ field2 ]'" -> match "[ field1 ]"
"[ field1 ] = '[ field2 ] field3'" -> match "[ field1 ]"
"[field1] = ' [field2] ' And [field3] = '[field4] '' [field5]'" -> match "[field1]" and "[field3]"

任何建议都将不胜感激!

2 个答案:

答案 0 :(得分:0)

当你需要匹配的东西"它们不在"之间。其他的事情,你可能认为是否定的lookaround

Region

匹配的组为(?<!' *)\[[^\]]*\](?! *') 。 如果我没有错,.NET regexps允许你在lookaround中使用非固定宽度表达式(但要注意它非常昂贵),所以上面的正则表达式应该可以完成这项任务。

在其他语言中,这是不允许的,但有一种称为&#34;占有量词的解决方法&#34; ($0):

*+

匹配的组为(?<!') *+(\[[^\]]*\]) *+(?!') 。 这适用于允许负面外观和占有量词的所有语言(example)。 关于$1的含义,我建议您my answer关于该主题。

但也许计算上最简单的表达式是:

*+

匹配的组为[^'] *+(\[[^\]]*\]) *+[^']

<强>更新

这是一种启发式方法:

$1

或者,也许更快:

(?<=^[^'\n\r]*(('[^'\n\r]*){2})*)\[[^\]]*\]

匹配的组为\[[^\]]*\](?=[^'\n\r]*(('[^'\n\r]*){2})*$) 。与multiline mode$0标志)一起使用。

如果不允许字段内的顶点,它将起作用。

答案 1 :(得分:0)

正如@horcrux也指出的那样,你可以使用负面的lookbehind和lookahead。因为显然C#支持无限重复,所以你可以逃避:

"(?<!(')\s*)" + "\[[^\[\]]+\]" + "(?!\s*$1)

分开三个部分,负面观察,捕捉匹配和否定前瞻。

另请注意,由于外观无法捕捉,因此您甚至不需要在中间部分使用括号。

Java中,这将是:

"(?<!(')\s{0,1000})" + "\[[^\[\]]+\]" + "(?!\s{0,1000}$1)

但它有点&#39; hacky,因为它只适用于两者之间的1000空格。