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