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



我想匹配括号中的所有单词,包括括号,这些单词不在简单引号之间(在 .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]"

任何建议将不胜感激!

当你需要匹配"不在"其他事物之间的事物时,你可能会想到负面的环顾四周:

(?<!' *)[[^]]*](?! *')

匹配的组是$0。 如果我没记错的话,.NET 正则表达式允许您在 lookaround 中使用非固定宽度表达式(但请注意它非常昂贵),因此上面的正则表达式应该可以完成这项工作。

在其他语言中,这是不允许的,但有一种称为"所有格量词"(*+)的解决方法:

(?<!') *+([[^]]*]) *+(?!')

匹配的组是$1。 这适用于所有允许否定环顾和所有格量词的语言(示例)。 关于*+的含义,我建议你回答这个话题。

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

[^'] *+([[^]]*]) *+[^']

匹配的组是$1


更新

这是一种启发式方法:

(?<=^[^'nr]*(('[^'nr]*){2})*)[[^]]*]

或者,也许更快:

[[^]]*](?=[^'nr]*(('[^'nr]*){2})*$)

匹配的组是$0。将其与多行模式(m标志)一起使用。

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

正如@horcrux还指出的那样,您可以使用负向后看和向前看。由于显然C#支持无限重复,因此您可以侥幸逃脱:

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

将三个部分分开,负向后看,捕获匹配和负向前看。

另请注意,由于环视是非捕获的,因此您甚至不需要在中间部分周围使用括号。

Java中,这将是这样的:

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

但它有点'笨拙,因为它只适用于两者之间的1000空间。

最新更新