Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正则表达式标记化问题_C#_Regex_Tokenize - Fatal编程技术网

C# 正则表达式标记化问题

C# 正则表达式标记化问题,c#,regex,tokenize,C#,Regex,Tokenize,我有用户输入的字符串,并希望标记它们。为此,我想使用正则表达式,现在有一个特殊情况的问题。 一个示例字符串是 Test+“Hello”+“Good\”more“+“Escape\”This\“Test” 或者C#等价物 @“Test+”“Hello”“+”“Good\”“more”“+”“Escape\”“This\”“Test”“” 我能够匹配测试和+标记,但不能匹配“测试”中包含的标记。我使用“让用户指定这实际上是一个字符串,而不是一个特殊的标记。现在,如果用户想在字符串中使用”字符,我想允

我有用户输入的字符串,并希望标记它们。为此,我想使用正则表达式,现在有一个特殊情况的问题。 一个示例字符串是

Test+“Hello”+“Good\”more“+“Escape\”This\“Test”
或者C#等价物

@“Test+”“Hello”“+”“Good\”“more”“+”“Escape\”“This\”“Test”“”

我能够匹配
测试
+
标记,但不能匹配“测试”中包含的标记。我使用“让用户指定这实际上是一个字符串,而不是一个特殊的标记。现在,如果用户想在字符串中使用”字符,我想允许他用\来转义它

所以规则是:给我两个“”之间的所有字符,但最后一个“不能是\”前面的字符

我期望的结果是:
“Hello”
“Good\”more““Escape\”这个“测试” 我需要在最终匹配中使用“”字符,这样我就知道这是一个字符串

我目前有一个regex
@”“([\w]*)(?它给出了以下结果:
“Hello”


所以后面的查找没有按我所希望的那样工作。有人知道获得我想要的字符串的正确方法吗?

下面是我用来解析命令行的正则表达式的一个改编:

(?!\+)((?:"(?:\\"|[^"])*"?|\S)+)
范例

(自适应是指忽略
+
并检查
\“
而不是
)的消极前瞻性操作)

希望这对你有帮助

问候

编辑:

如果您对周围的引号不感兴趣:

(?!\+)(?:"((?:\\"|[^"])*)"?|(\S+))

为了更安全,我建议使用以下正则表达式获取
“…”
的未替换对中的所有子字符串:

^(?:[^"\\]*(?:\\.[^"\\]*)*("[^"\\]*(?:\\.[^"\\]*)*"))+
相配

  • ^
    -字符串的开头(以便我们可以检查每个
    和转义序列)
  • (?:
    -非捕获组1用作后续子模式的容器
    • [^“\\]*(?:\..^“\\]*)*
      -匹配0+字符,而不是
      \
      ,后跟0+序列的
      \.
      (任何转义序列),后跟0+字符,而不是
      \
      (因此,我们避免匹配第一个
      这是转义的,它前面可以有任意数量的转义序列)
    • (“[^”\\]*(?:\.[^”\]*)*”
      -捕获组1中匹配的
      “…”
      子字符串,其中可能包含任何转义序列
  • )+
    -重复1次或多次的第一个非捕获组的结束
请参阅,这里是一个:

var rx=“^(?:[^\“\\\\]*(?:\\\\..^\\\\]*)*(\“[^\\\\\]*(?:\\\\\.^\\\\\]*)*)+”;
var s=@“Test+”“Hello”“+”“Good\”“more”“+\”“Escape\”“This\”“Test\”“f”“;
var matches=正则表达式匹配(s,rx)
.Cast()
.SelectMany(m=>m.Groups[1]。Captures.Cast().Select(p=>p.Value.ToArray())
.ToList();
Console.WriteLine(string.Join(“\n”,匹配项));
更新

如果需要删除令牌,只需使用以下代码匹配并捕获它们之外的所有令牌:

var keep = "[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*";
var rx = string.Format("^(?:(?<keep>{0})\"{0}\")+(?<keep>{0})$", keep);
var s = @"Test + ""Hello"" + ""Good\""more"" + \""Escape\""This\""Test\"" + ""f""";
var matches = Regex.Matches(s, rx)
        .Cast<Match>()
        .SelectMany(m => m.Groups["keep"].Captures.Cast<Capture>().Select(p => p.Value).ToArray())
        .ToList();
Console.WriteLine(string.Join("", matches));
var keep=“[^\”\\\]*(?:\\\\\.[^\“\\\\]*)*”;
var rx=string.Format(“^(?({0})\{0}\”+({0})$”,保留);
var s=@“Test+”“Hello”“+”“Good\”“more”“+\”“Escape\”“This\”“Test\”“f”“;
var matches=正则表达式匹配(s,rx)
.Cast()
.SelectMany(m=>m.Groups[“keep”].Captures.Cast().Select(p=>p.Value.ToArray())
.ToList();
Console.WriteLine(string.Join(“,matches));


输出:
Test++\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>好\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。这甚至会匹配。这看起来很好。但是,对于标记化,我想用空字符串替换输入字符串中的匹配项,因为我有多个用于不同目的的表达式。您的正则表达式将整个字符串作为匹配项提供给我,那么删除匹配项的最安全方法是什么?我可以替换第一次出现的eac正则表达式找到的字符串的h,但我想知道这是否是一种安全的方法。好的,那么您需要删除
“Hello”
“Good\”more“
,以及
“f”
,对吗?让我检查一下。。。
var keep = "[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*";
var rx = string.Format("^(?:(?<keep>{0})\"{0}\")+(?<keep>{0})$", keep);
var s = @"Test + ""Hello"" + ""Good\""more"" + \""Escape\""This\""Test\"" + ""f""";
var matches = Regex.Matches(s, rx)
        .Cast<Match>()
        .SelectMany(m => m.Groups["keep"].Captures.Cast<Capture>().Select(p => p.Value).ToArray())
        .ToList();
Console.WriteLine(string.Join("", matches));