给定输入字符串:
V1 valueA=somethingA Version Data valueB="something longer" "diagnostic data"
如何获取正则表达式查询以将其拆分为构成部分:
[0] V1
[1] valueA=somethingA
[2] Version
[3] Data
[4] valueB="something longer"
[5] "diagnostic data"
我一直试图复活我很久以前最后一次使用的正则表达式体验,但这让我疯了。我得到的最接近的是这个表达式:
[\""].+?[\""]|[^ ]+
答案 0 :(得分:4)
尝试匹配您想要的所有部分,而不是尝试拆分。这是原始模式(没有任何转义):
[^\s"]+(?:"[^"]*"[^\s"]*)*|(?:"[^"]*"[^\s"]*)+
请注意,这是一般模式,对于您的特定情况(属性类型),这样的事情就足够了:
[^\s"]+(?:"[^"]*")?|"[^"]*"
要允许等号周围的空格,您还可以写:
[^\s"=]+(?:\s*=(?:\s*"[^"]*"|\S+))?|"[^"]*"
答案 1 :(得分:0)
使用负向前看你可以按空格分割。仅当空格前面没有句子"
:
string g = "V1 valueA=somethingA Version Data valueB=\"something longer\" \"diagnostic data\"";
string [] res = Regex.Split(g, @"(?<!""\w+)\s");
结果:
说明:
\s
匹配空格
(?<!""(\w+\s)?\w+)
只有在没有单词
""(\w+\s)?
前面有一个可选字词和一个空格,开头有一个"
答案 2 :(得分:0)
如果使用选项RegexOptions.RightToLeft
告诉正则表达式解析器在文本字符串上向后工作,则会使模式更容易解开。 了解解析器在字符串上向后工作,但我们的模式仍在前进。
只需查找引号(在我的模式中,我使用\x22
处的引号的十六进制值以便于阅读),如果找到一个匹配前一个引号,则匹配到下一个空格,否则当没有引用只是匹配所有直到下一个空格。
[^\s]* # We *may* have the proceeding xxx= so match til a space
(\x22[^\x22]+\x22) # Match the quoted stuff such as "xxx"
| # Or
[^\s]+ # No quotes so extract all text til the white space
上述模式已被评论,因此需要RegexOptions.IgnorePatternWhiteSpace
,否则oneline上的模式为
[^\s]*(\x22[^\x22]+\x22)|[^\s]+
结果
您的数据
V1 valueA=somethingA Version Data valueB="something longer" "diagnostic data"
以下[x]
是提取数据的组号(如果适用)。
Match #0
[0]: "diagnostic data"
["1"] → [1]: "diagnostic data"
Match #1
[0]: valueB="something longer"
["1"] → [1]: "something longer"
Match #2
[0]: Data
["1"] → [1]:
Match #3
[0]: Version
["1"] → [1]:
Match #4
[0]: valueA=somethingA
["1"] → [1]:
Match #5
[0]: V1
["1"] → [1]:
请注意,匹配从结束到开始都有效,因此您可能需要在提取期间向匹配数组向后工作才能获得正确的方向。 : - )