我在 C# 中有一个具有以下模式的正则表达式
Regex param = new Regex(@"^-|^/|=|:");
基本上,它用于命令行解析。
如果我通过下面的 cmd 行参数,它也会溢出C:
。
/Data:SomeData /File:"C:\Somelocation"
如何使其不适用于双引号或单引号内的字符?
您可以分两步执行此操作:
使用第一个正则表达式
Regex args = new Regex("[/-](?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
将字符串拆分为不同的参数。然后使用正则表达式
Regex param = new Regex("[=:](?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
将每个参数拆分为参数/值对。
解释:
[=:] # Split on this regex...
(?= # ...only if the following matches afterwards:
(?: # The following group...
[^"]*" # any number of non-quote character, then one quote
[^"]*" # repeat, to ensure even number of quotes
)* # ...repeated any number of times, including zero,
[^"]* # followed by any number of non-quotes
$ # until the end of the string.
) # End of lookahead.
基本上,如果前面有偶数个引号,它会在字符串中向前看。如果有,我们就在字符串之外。但是,这个(有点可管理的)正则表达式只处理双引号,并且只有在其中没有转义引号的情况下。
以下正则表达式正确处理单引号和双引号,包括转义引号。但我想你会同意,如果有人在生产代码中发现了这个,我保证会在The Daily WTF上发表一篇专题文章:
Regex param = new Regex(
@"[=:]
(?= # Assert even number of (relevant) single quotes, looking ahead:
(?:
(?:\\.|""(?:\\.|[^""\\])*""|[^\\'""])*
'
(?:\\.|""(?:\\.|[^""'\\])*""|[^\\'])*
'
)*
(?:\\.|""(?:\\.|[^""\\])*""|[^\\'])*
$
)
(?= # Assert even number of (relevant) double quotes, looking ahead:
(?:
(?:\\.|'(?:\\.|[^'\\])*'|[^\\'""])*
""
(?:\\.|'(?:\\.|[^'""\\])*'|[^\\""])*
""
)*
(?:\\.|'(?:\\.|[^'\\])*'|[^\\""])*
$
)",
RegexOptions.IgnorePatternWhitespace);
这里对这个怪物做进一步的解释。
您应该阅读“掌握正则表达式”以了解为什么您的问题没有通用解决方案。正则表达式无法将其处理到任意深度。一旦您开始转义转义字符或转义转义字符或...您就迷路了。您的用例需要解析器而不是正则表达式。