现在我使用的是 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 库有选项)。 但是,我不想使用 Boost 库。
有很多用 Perl 编写的正则表达式,所以我想将现有的 Perl 正则表达式转换为
ECMAScript
(或 VC++ 2010 支持的任何一个)。转换后,我可以直接在 VC++ 2010 中使用等效的正则表达式,而无需使用第三方库。一个例子:
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
样式表达式。是否可以找到将所有 Perl 正则表达式转换为
ECMAScript
样式的通用方法?有没有一些工具可以做到这一点?
任何帮助将不胜感激!
最佳答案
对于要转换的特定正则表达式,ECMA 正则表达式中的等效项是:
/^(\d{3,4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})$/
在这种情况下,
\A
(在 Perl 正则表达式中)与 ^
具有相同的含义(在 ECMA 正则表达式中)(匹配字符串的开头)和 \Z
(在 Perl 正则表达式中)与 $
具有相同的含义(在 ECMA 正则表达式中)(匹配字符串的结尾)。注意^
的含义和 $
如果启用多行模式,ECMA 正则表达式将更改为匹配行的开头和结尾。ECMA regex 是 Perl regex 的子集,因此如果 regex 使用 Perl regex 中的专有功能,它很可能无法转换为 ECMA regex。即使对于相同的语法,正则表达式的两种方言之间的语法也可能略有不同,因此检查文档并比较用法总是明智的。
我只想说 ECMA regex 和 Perl regex 之间的相似之处。什么不相似,但可以转换,我会尽量提一下。
ECMA 正则表达式缺乏与 Unicode 一起使用的功能,这迫使您查找代码点并将它们指定为字符类。
按照 documentation for Perl regular expression :
i
, g
, m
在 ECMA 标准中,它们的行为与在 Perl 中相同。 s
可以通过使用 2 个补充字符类在 ECMA 正则表达式中模拟点全修饰符,例如[\S\s]
, [\D\d]
x
和 p
旗帜。 \
有点怀疑具有不解析为任何特殊含义的非元字符,但是如果您不从不需要的地方逃生应该没问题。 .
在 ECMA 中排除了更多字符。其余的在 ECMA 正则表达式中的行为相同(即使 m
标志对 ^
和 $
的影响)。 \a
和 \e
在 ECMA 正则表达式中。 \t
, \n
, \r
, \f
是相同的。 \cX
,请检查文档- 存在差异。 \xhh
在 ECMA regex 和 Perl regex 中很常见(指定 2 个十六进制数字是最安全的 - 否则,您将不得不查找文档以了解该语言将如何处理少于 2 个十六进制数字的情况)。 \uhhhh
是 ECMA 正则表达式独有的功能,用于指定 Unicode 字符。 Perl 有其他独有的方式来指定字符,例如 \x{}
, \N{}
, \o{}
, \000
. \l
, \u
, \L
, \U
是 Perl 正则表达式独有的。 \Q
和 \E
可以通过手动转义引用的部分来模拟。 \w
, \W
, \s
, \S
, \d
, \D
如果假设为 US-ASCII,则在 ECMA 正则表达式和 Perl 正则表达式中是等效的。如果涉及到 Unicode,事情将变得一团糟。 \w
, \s
, \d
或在字符类中指定自己。 []
和已经提到的转义序列)在 ECMA 正则表达式中不受支持。 \b
和 \B
关于如何基于 \w
定义它们在两种语言中是等效的. ()
和反向引用是一样的。 $n
,在替换字符串中用于反向引用匹配的文本,是相同的。本节中的其余部分是 Perl 独有的功能。 s
标志是一种始终可以转换为 ECMA 正则表达式中的等效表达式的标志)。 (?:pattern)
(非捕获组),(?=pattern)
(正面展望),(?!pattern)
(负面展望)在 Perl 和 ECMA 之间很常见。 (?#text)
可以忽略。 结论 :
如果正则表达式充分利用了 Perl 正则表达式的全部功能,或者在 Boost 库支持的级别(例如递归正则表达式),则无法将正则表达式转换为 ECMA 正则表达式。幸运的是,ECMA 正则表达式涵盖了最常用的功能,因此正则表达式很可能是可转换的。
引用 :
ECMA RegExp Reference on MDN
关于c++ - 将 Perl 正则表达式转换为等效的 ECMAScript 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12127463/