现在我正在使用VC ++ 2010,但VC ++ 2010的syntax_option_type
只包含以下选项:
static const flag_type icase = regex_constants::icase; static const flag_type nosubs = regex_constants::nosubs; static const flag_type optimize = regex_constants::optimize; static const flag_type collate = regex_constants::collate; static const flag_type ECMAScript = regex_constants::ECMAScript; static const flag_type basic = regex_constants::basic; static const flag_type extended = regex_constants::extended; static const flag_type awk = regex_constants::awk; static const flag_type grep = regex_constants::grep; static const flag_type egrep = regex_constants::egrep;
它不包含perl_syntax_group(Boost Library有选项)。 但是,我不想使用Boost库。
Perl中有很多正则expression式,所以我想把现有的Perl正则expression式转换成ECMAScript
(或者VC ++ 2010支持的任何一种)。 转换后,我可以直接在VC ++ 2010中使用等效的正则expression式,而不使用第三方的libray。
一个例子:
const boost::tregex e(__T("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z")); const CString human_format = __T("$1-$2-$3-$4"); CString human_readable_card_number(const CString& s) { return boost::regex_replace(s, e, human_format); } CString credit_card_number = "1234567887654321"; credit_card_number = human_readable_card_number(credit_card_number); assert(credit_card_number == "1234-5678-8765-4321");
在上面的例子中,我想要做的是将e
和format
转换成ECMAScript
风格的expression式。
有没有可能find一种将所有Perl正则expression式转换为ECMAScript
风格的一般方法? 有没有一些工具可以做到这一点?
任何帮助将不胜感激!
对于要转换的特定正则表达式,ECMA正则表达式中的等价物是:
/^(\d{3,4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})$/
在这种情况下, \A
(在Perl正则表达式中)与^
(在ECMA正则表达式中)(匹配字符串的开头)和\Z
(在Perl正则表达式中)具有与$
(在ECMA正则表达式中)字符串的结尾)。 请注意,如果启用多行模式,ECMA正则表达式中的^
和$
含义将更改为匹配行的开头和结尾。
ECMA正则表达式是Perl正则表达式的一个子集,所以如果正则表达式在Perl正则表达式中使用独有的功能,它很可能不能转换成ECMA正则表达式。 即使是相同的语法,语法也许意味着2种正则表达式之间的差别,所以检查文档和比较使用总是明智的。
我只是想说ECMA正则表达式和Perl正则表达式之间的相似之处。 什么是不相似的,但敞篷车,我会提到我的最大能力。
ECMA正则表达式缺少使用Unicode的功能,这迫使您查找代码点并将它们指定为字符类。
根据Perl正则表达式的文档 :
i
, g
, m
在ECMA标准中,并且与Perl中的行为相同。 [\S\s]
, [\D\d]
来模拟点全部修饰符。 x
和p
标志。 \
并没有解决任何特殊含义,我有点怀疑,但是如果你不需要转义的话,它应该没问题。 .
在ECMA中排除了几个字符。 其余的行为在ECMA正则表达式中是相同的(甚至在^
和$
上有m
标志的效果)。 \a
和\e
。 \t
, \n
, \r
, \f
是一样的。 \cX
– 有差异。 \xhh
在ECMA正则表达式和Perl正则表达式中很常见(指定2个十六进制数字是最安全的 – 否则,您将不得不查看文档以查看语言将如何处理少于2个十六进制数字的情况)。 \uhhhh
是ECMA正则表达式的独有功能来指定Unicode字符。 Perl有其他独特的方式来指定字符,如\x{}
, \N{}
, \o{}
, \000
。 \l
, \u
, \L
, \U
是Perl正则表达式专有的 。 \Q
和\E
可以通过手动转义引用部分来模拟。 \w
, \W
, \s
, \S
, \d
, \D
在ECMA正则表达式和Perl正则表达式中是等价的,如果使用US-ASCII。 如果涉及Unicode,事情将是一个混乱的血腥。 \w
, \s
, \d
或者在字符类中指定自己。 []
和已经提到的转义序列)在ECMA正则表达式中不受支持。 \b
和\B
在两种语言中是相同的,关于如何根据\w
定义它们。 ()
和后向引用是相同的。 在替换字符串中用来反向引用匹配文本的$n
是相同的。 其余部分是Perl独有的功能。 s
标志是一个总是可以转换成ECMA正则表达式的等价表达式)。 (?:pattern)
(非捕获组), (?=pattern)
(正面向前看), (?!pattern)
(负面向前看)是常见的。 (?#text)
可以被忽略。 结论 :
如果正则表达式利用Perl正则表达式的全部功能,或者在Boost库支持的级别(例如递归正则表达式),则不可能将正则表达式转换为ECMA正则表达式。 幸运的是,ECMA正则表达式覆盖了最常用的功能,因此正则表达式可能是可转换的。
参考 :
ECM RegExp参考MDN