所以,我需要在c#regex中做什么,每当我找到某个模式时,基本上会拆分一个字符串,但如果它被字符串中的双引号包围,则忽略该模式。
示例:
string text = "abc , def , a\" , \"d , oioi";
string pattern = "[ \t]*,[ \t]*";
string[] result = Regex.Split(text, pattern, RegexOptions.ECMAScript);
分割后想要结果(3个分割,4个字符串):
{"abc",
"def",
"a\" , \"d",
"oioi"}
实际结果(4个分组,5个字符串):
{"abc",
"def",
"a\"",
"\"d",
"oioi"}
另一个例子:
string text = "a%2% 6y % \"ad%t6%&\" %(7y) %";
string pattern = "%";
string[] result = Regex.Split(text, pattern, RegexOptions.ECMAScript);
分割后想要结果(5个分割,6个字符串):
{"a",
"2",
" 6y ",
" \"ad%t6%&\" ",
"(7y) ",
""}
实际结果(7个分组,8个字符串):
{"a",
"2",
" 6y ",
"\"ad",
"t6",
"&\" ",
"(7y) ",
""}
第三个例子,举例说明一个棘手的分裂,其中只应忽略第一种情况:
string text = "!!\"!!\"!!\"";
string pattern = "!!";
string[] result = Regex.Split(text, pattern, RegexOptions.ECMAScript);
分割后想要结果(2个分割,3个字符串):
{"",
"\"!!\"",
"\""}
实际结果(3个分组,4个字符串):
{"",
"\"",
"\"",
"\"",}
那么,如何从模式转移到实现所需结果的新模式?
旁注:如果你要将某人的问题标记为重复(并且我没有反对),至少指出正确的答案,而不是一些随机的帖子(是的,我在看着你,Mr .Avinash Raj)......
答案 0 :(得分:2)
除了:
之外,规则或多或少类似于csv行首先,当您想要使用一些高级规则来分隔项目(拆分)时,拆分方法不再是一个好的选择。拆分方法仅适用于简单情况,而不适用于您的情况。 (即使没有孤立引号,使用与,(?=(?:[^"]*"[^"]*")*[^"]*$)
分割也是一个非常糟糕的主意,因为解析字符串所需的步骤数会随着字符串大小呈指数级增长。)
另一种方法是捕获物品。这更简单,更快捷。 (奖励:它同时检查整个字符串的格式。)
以下是执行此操作的一般方法:
^
(?>
(?:delimiter | start_of_the_string)
(
simple_part
(?>
(?: quotes | delim_first_letter_1 | delim_first_letter_2 | etc. )
simple_part
)*
)
)+
$
以\s*,\s*
作为分隔符的示例:
^
# non-capturing group for one delimiter and one item
(?>
(?: \s*,\s* | ^ ) # delimiter or start of the string
# (eventually change "^" to "^ \s*" to trim the first item)
# capture group 1 for the item
( # simple part of the item (maybe empty):
[^\s,"]* # all that is not the quote character or one of the possible first
# character of the delimiter
# edge case followed by a simple part
(?>
(?: # edge cases
" [^"]* (?:"|$) # a quoted part or an orphan quote in the last item (*)
| # OR
(?> \s+ ) # start of the delimiter
(?!,) # but not the delimiter
)
[^\s,"]* # simple part
)*
)
)+
$
demo (点击表格链接)
该模式是为Regex.Match
方法设计的,因为它描述了所有字符串。所有项目都在组1中可用,因为.net正则表达式风格能够存储重复的捕获组。
这个例子很容易适应所有情况。
(*)如果您想在引用的部分中允许转义引号,则可以再使用一次simple_part (?: edge_case simple_part)*
而不是" [^"]* (?:"|$)
,即:{ {1}}
答案 1 :(得分:0)
我认为这是一个两步的过程,它已经被推翻,试图让它成为一步正则表达式。
<强>步骤强>
流程示例
我会在,
上拆分第2步。
var data = string.Format("abc , def , a{0}, {0}d , oioi", "\"");
// `\x22` is hex for a quote (") which for easier reading in C# editing.
var stage1 = Regex.Replace(data, @"\x22", string.Empty);
// abc , def , a", "d , oioi
// becomes
// abc , def , a, d , oioi
Regex.Matches(stage1, @"([^\s,]+)[\s,]*")
.OfType<Match>()
.Select(mt => mt.Groups[1].Value )
<强>结果强>