我有这个.NET正则表达式:
^(?<prefix>("[^"]*"))\s(?<attrgroup>(\([^\)]*\)))\s(?<suffix>("[^"]*"))$
它恰当地匹配以下字符串:
"some prefix" ("attribute 1" "value 1") "some suffix"
"some prefix" ("attribute 1" "value 1" "attribute 2" "value 2") "some suffix"
它失败了......
"some prefix" ("attribute 1" "value (fail) 1") "some suffix"
...由于“失败”之后的正确选择。
如何修改我的正则表达式,以便attrgroup
匹配组最终包含“("attribute 1" "value (fail) 1")
”?我一直在看它太久了,需要一些新鲜的眼睛。谢谢!
编辑: attrgroup
除了双引号字符串之外不会包含任何内容。
答案 0 :(得分:2)
我未经考验的猜测:
^(?<prefix>("[^"]*"))\s(?<attrgroup>(\(("[^"]*")(\s("[^"]*")*)**\)))\s(?<suffix>("[^"]*"))$
特此我已经取代了
[^\)]*
与
("[^"]*")(\s("[^"]*")*)*
我假设括号内的所有内容都在双引号之间,或者是一个空格。
如果您想知道我是如何做到这一点的,请阅读Mastering Regular Expressions。
PS。如果我是正确的,那么这也将验证属性组作为引用字符串对。
答案 1 :(得分:1)
^(?<prefix>"[^"]*")\s+(?<attrgroup>\(.*\))\s+(?<suffix>"[^"]*")$
为我修好了。
我删除了无关的未命名组并简化了属性组(简称为“任意字符”)。
非常值得投资的将是JG Soft的RegexBuddy
编辑:这不会将属性组验证为引用字符串对,但应该/可以在单独的正则表达式/验证步骤中完成。
答案 2 :(得分:0)
Hometoasts解决方案是一个很好的解决方案,虽然像任何自由主义正则表达式一样,它只应用于从您有合理保证的来源提取数据,而不是用于验证。
答案 3 :(得分:0)
如果不解决此正则表达式的细节,我建议使用Regex工具来帮助构建,测试和验证正则表达式。对于任何非常重要的事情,或者您可能需要维护/更新的表达,这些工具都是必不可少的。
退房......
The Regex Coach - 用Lisp写的,有点老了,但我真的更喜欢这个给别人。
Rad Software Regex Designer - .NET也许更“现代”。有些人可能喜欢这个。
答案 4 :(得分:0)
我建议使用能够处理此类结构的解析器。正则表达式失败,这是正确的,因为您尝试解析的语言看起来不规律 - 至少从上面给出的示例中看。每当你需要识别嵌套时,正则表达式会失败或变成像上面那样复杂的野兽。即使语言是规则的,那里的常规表达看起来对我来说太复杂了。我宁愿使用这样的东西:
def parse_String(string):
index = skip_spaces(string, 0)
index, prefix = read_prefix(string, index)
index = skip_spaces(string, index)
index, attrgroup = read_attrgroup(string, index)
index = skip_spaces(string, index)
index, suffix = read_suffix(string, index)
return prefix, attrgroup, suffix
def read_prefix(string, start_index):
return read_quoted_string(string, start_index)
def read_attrgroup(string, start_index):
end_index, content = read_paren(string, start_index)
index = skip_spaces(content, 0)
index, first_entry = read_quoted_string(content, index)
index = skip_spaces(content, index)
index, second_entry = read_quoted_string(content, index)
return end_index, (first_entry, second_entry)
def read_suffix(string, start_index):
return read_quoted_string(string, start_index)
def read_paren(string, start_index):
return read_delimited_string(string, start_index, '(', ')')
def read_quoted_string(string, start_index):
return read_delimited_string(string, start_index, '"', '"')
def read_delimited_string(string, starting_index, start_limiter, end_limiter):
assert string[starting_index] == start_limiter, (start_limiter
+"!="
+string[starting_index])
current_index = starting_index+1
content = ""
while(string[current_index] != end_limiter):
content += string[current_index]
current_index += 1
assert string[current_index] == end_limiter
return current_index+1, content
def skip_spaces(string, index):
while string[index] == " ":
index += 1
return index
是的,这是更多的代码,是的,按原始数量,这需要更长的时间。但是 - 至少对我来说 - 我的解决方案更容易验证。如果通过将所有这些移动到类中来删除一堆字符串和索引管道,这会增加更多,这会在它的构造函数中解析这些字符串。此外,很容易使空间跳过隐式(使用一些魔术next-char方法,只是跳过字符直到出现非空格,除非由于字符串而处于某种非跳过模式。此模式可以设置为例如,分隔函数。这会将parse_string转换为:
def parse_string(string):
prefix = read_prefix()
attrgroup = read_attr_group()
suffix = read_suffix()
return prefix, attrgroup, suffix.
此外,这个功能可以更容易地扩展到更复杂的表达。任意嵌套的attrgroups?更改一行代码。嵌套的parens?多一点工作,但没有真正的问题。
现在,请为我做一些正则表达式和一些解析器倡导者而呐喊我。 &GT;:)
PS:是的,该代码未经测试。据我所知,那里有三个错字,我没有看到。