我在Perl中有一些有用的正则表达式。有没有简单的方法将它们翻译成.NET的正则表达式方言?
如果没有,是否有简明的差异参考资料?
http://www.regular-expressions.info/refflavors.html 中有一个很大的比较表格。
大多数基本元素都是相同的,不同之处在于:
次要差异:
\u200A
,在 Perl 中为 \x{200A}
。\v
仅表示垂直制表符(U+000B),而在 Perl 中它代表 "垂直空白" 类别。当然,在 Perl 中有 \V
。(?(name)yes|no)
,但在 Perl 中为 (?(<name>)yes|no)
。一些元素仅存在于 Perl 中:
x?+
、x*+
、x++
等等)。使用非回溯子表达式((?>…)
)代替。\N{LATIN SMALL LETTER X}
、\N{U+200A}
。\l
(下一个字符转换为小写)、\u
(下一个字符转换为大写)。\L
(全部转换为小写)、\U
(全部转换为大写)、\Q
(引用元字符直到 \E
)。\pL
和 \PL
。在 .NET 中必须包含花括号,例如:\p{L}
。\X
、\C
。\v
、\V
、\h
、\H
、\N
和\R
\g1
、\g{-1}
。在.NET中只能使用绝对组索引。\g{name}
。请改用\k<name>
。[[:alpha:]]
。(?|…)
\K
。请改用正向先行断言((?<=…)
)。(?{…})
,延迟子表达式(??{…})
。(?0)
、(?R)
、(?1)
、(?-1)
、(?+1)
、(?&name)
。(?{…})
(R)
、(R1)
、(R&name)
(DEFINE)
。 (*VERB:ARG)
(?P<name>…)
。请改用(?<name>…)
。(?P=name)
。请改用\k<name>
。(?P>name)
。在.NET中没有相应的语法。一些元素只适用于.NET:
\K
。(?(pattern)yes|no)
。[a-z-[d-w]]
(?<-name>…)
。这可以通过代码评估断言(?{…})
后跟一个(?&name)
来模拟实现。参考资料:
它们被 设计成与 Perl 5 正则表达式兼容。因此,Perl 5 正则表达式 应该 在 .NET 中正常工作。
您可以将一些RegexOptions
翻译如下:
[Flags]
public enum RegexOptions
{
Compiled = 8,
CultureInvariant = 0x200,
ECMAScript = 0x100,
ExplicitCapture = 4,
IgnoreCase = 1, // i in Perl
IgnorePatternWhitespace = 0x20, // x in Perl
Multiline = 2, // m in Perl
None = 0,
RightToLeft = 0x40,
Singleline = 0x10 // s in Perl
}
另一个提示是使用原始字符串,这样您就不需要在C#中转义所有这些转义字符:
string badOnTheEyesRx = "\\d{4}/\\d{2}/\\d{2}";
string easierOnTheEyesRx = @"\d{4}/\d{2}/\d{2}";
(?{ code })
和 (??{ code })
,能够递归到捕获组... - Eric Strom这真的取决于正则表达式的复杂性 - 许多正则表达式可以直接使用相同的方式工作。
查看this .NET 正则表达式速查表,以查看运算符是否按照您的预期进行操作。
我不知道是否有任何工具可以自动翻译正则表达式方言之间的差异。
perl -E "@captures = 'word1 word2 word3' =~ /(?<name1>\w+)\s+(\w+)\s+(\w+)/; foreach my $c (@captures){say $c}"
仍然输出为word1 word2 word3
,而在.NET正则表达式中,它将输出为word2 word3 word1
,因为未命名组在正则表达式引擎按顺序排列捕获组时具有优先级。这可能会对从一种语言翻译成另一种语言的复杂正则表达式产生影响。 - knb