正则表达式,用于查找非转义字符

时间:2011-11-12 23:05:38

标签: .net regex

我需要找到格式为_x[0-9A-F]{4}_的十六进制字符,除非它们前面有_x005F(使用.Net)

我尝试了[^(_x005F)]_x[0-9A-F]{4}_,但它不起作用,因为它匹配字符串_x005F_上的AA_x005F_x00FF_BB(在这种情况下,我不希望它匹配任何内容)。

4 个答案:

答案 0 :(得分:1)

您需要使用负面的背后隐藏。像这样:

(?<!_x005F)_x[0-9A-F]{4}_

答案 1 :(得分:0)

你需要使用负面的lookbehind:

(?<!pattern)

例如:

(?<!_x005F)x[0-9A-F]{4}_

修改 - 更正后的答案

答案 2 :(得分:0)

你的问题并没有说清楚,但你似乎有两个非常相似的要求:

  • 如果之前的字符为x005F,则不匹配。
  • 如果当前字符为x005F,则不匹配。

试试这个:

"(?<!_x005F)_x(?!005F)[0-9A-F]{4}_"

完整示例:

string s = "AA_x0042_x005F_x00FF_x0043_BB";
foreach (Match match in Regex.Matches(s, "(?<!_x005F)_x(?!005F)[0-9A-F]{4}_"))
{
    Console.WriteLine(match.Value);
}

输出:

_x0042_
_x0043_

查看在线工作:ideone

答案 3 :(得分:0)

您尝试使用[^(_x005F)]做什么应该是负面的背后隐藏:(?<!_x005F)。但它并没有真正起作用,因为Mark Byers指出:它错误地匹配转义的十六进制序列中的前导_x005F_,例如_x005F_x00FF_

然而,我没有Mark的解决方案,增加的负面前瞻也可以;格式错误的文字似乎让它失去了同步,正如我在评论中所描述的那样。我相信与hex / escape序列保持同步的唯一可靠方法是匹配非转义十六进制序列之间的所有文本,并使用捕获组来提取所需的部分。这个正则表达式对我有用:

\G(?>(?>(?:(?!_x[0-9A-F]{4}_).)+|_x005F_x[0-9A-F]{4}_)*)(_x[0-9A-F]{4}_)

我知道这看起来很可怕,但请耐心等待。 :D这是细分:

  • \G将匹配在第一次迭代时锚定到字符串的开头,然后锚定到最后一次匹配结束的位置。

  • (?:(?!_x[0-9A-F]{4}_).)+反复使用任何字符,除非前瞻确定它是十六进制序列的第一个字符。

  • _x005F_x[0-9A-F]{4}_使用转义的十六进制序列。

  • (?>(?:(?!_x[0-9A-F]{4}_).)+|_x005F_x[0-9A-F]{4}_)*尽可能多地重复这些替代方案。当它退出时,接下来的事情必须是字符串的结尾或未转义的十六进制序列,它将在第1组中被捕获......

  • (_x[0-9A-F]{4}_)

这是一个online demo,其输出是:

abc_x0011_def_x005F__x0022_ghi_x005F_x0033_jkl_x0042_x005F_x00FF_x0043_mno
   ^^^^^^^   ^^^^^^^^^^^^^^                   ^^^^^^^     ^^^^^^^         

_x0011_
_x005F_
_x0022_
_x0042_
_x00FF_

由于尾​​随下划线,第一个_x005F_不会转义以下_x0022_。我不知道是否可以像这样独立,但我不明白为什么不应该这样。下一个_x005F 转义_x0033_

样本的其余部分展示了我认为Mark解决方案的错误。但可能是我错了;我不知道你正在使用的语言的完整语法。