2016-03-04 84 views
1

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

Test + "Hello" + "Good\"more" + "Escape\"This\"Test" 或C#相当于

@"Test + ""Hello"" + ""Good\""more"" + ""Escape\""This\""Test"""

我能够匹配Test+令牌,但不包含那些的。“我用的是”让用户指定这是字面上的字符串而不是特殊的标记。现在,如果用户想使用“字符串中的字符,我认为这让他以\逃避它的

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

我期望的结果是:"Hello""Good\"more""Escape\"This\"Test" 我需要的“”字是在最后一场比赛,所以我知道这是一个字符串。

我现在有这给了我,结果如下正则表达式@"""([\w]*)(?<!\\"")""""Hello""more"​​

所以后面看看是不是工作,我希望它是。有谁知道正确的方式来获得像我想要的字符串?

+1

还有一个级别:\通常可以用另一个\\ \ ...来转义...所以'\\'''''''' – xanatos

+0

Xanatos是对的,否则,['“[^”\\] * (?:\\ [^ “\\] *)*”'](http://regexstorm.net/tester?p=%22%5b%5e%22%5c%5c%5d*(%3F%图3a%5C%5c所示。%图5b%5E%22%5C%5C%5D *)*%22&I =测试+%2B +%22Hello%22 +%2B +%22Good%5C%22more%22 +%2B +%22%图5c% 5c%5c%22Escape%5c%22This%5c%22Test%22&o = ixncsm)应该为你工作(C#['var rx =“\”[^ \“\\\\] *(?:\\\\。 [^ \ “\\\\] *)* \”“'](http://ideone.com/dTq91U))。 –

回答

1

这里的一个正则表达式的适应我使用解析命令行:

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

here at regex101

(适配是负先行忽略+和检查\"代替""

希望这可以帮助你。

问候。

编辑:

如果你不感兴趣的包围引号:

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

这甚至会匹配['Test + \“Hello”+ \“Good \”more“+ \”Escape \“This \”Test“'](https://regex101.com/r/yE2vW7/2)。 –

1

为了使它更安全,我建议让转义双"..."具有以下的正则表达式中的所有字符串:

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

它匹配

  • ^ - 非捕获组1用作用于随后的子模式
    • [^"\\]*(?:\\.[^"\\]*)*容器 - - 比赛0+字符以外的字符串(这样我们就可以检查每个"和逸出序列)
    • (?:的开始比"\随后用\\. 0+序列(任何转义序列),然后以比"\(因此,我们避免匹配被转义第一",并且它可以与任何数量的电子商务前面其他0+字符花茎序列)
    • ("[^"\\]*(?:\\.[^"\\]*)*") - 捕获组1匹配"..."子可能含有内部
  • )+任何转义序列 - 被重复第一非捕获组的端部1次或更多次

regex demo,这里是一个C# demo

var rx = "^(?:[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"))+"; 
var s = @"Test + ""Hello"" + ""Good\""more"" + \""Escape\""This\""Test\"" + ""f"""; 
var matches = Regex.Matches(s, rx) 
     .Cast<Match>() 
     .SelectMany(m => m.Groups[1].Captures.Cast<Capture>().Select(p => p.Value).ToArray()) 
     .ToList(); 
Console.WriteLine(string.Join("\n", matches)); 

UPDATE

如果您需要删除的标记,只是匹配,并且捕捉他们的一切外,此代码:

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)); 

another demo

输出:Test + + + \"Escape\"This\"Test\" +@"Test + ""Hello"" + ""Good\""more"" + \""Escape\""This\""Test\"" + ""f""";

+0

这看起来非常好,但是对于标记我想用空字符串替换我的输入字符串中的匹配,因为我有多个表达式用于不同的目的,你的正则表达式使我匹配整个字符串,那么最安全的是什么我可以替换正则表达式中每个字符串的第一次出现,但我想知道这是否安全。 – RBS

+0

好的,所以你需要删除''你好'',''好\“more”'和''f“',对吗?让我检查一下... –

+0

检查[此演示](http://ideone.com/MAIWJv)。 –