![](/img/trans.png)
[英]Convert Regular Expression pattern from Javascript to PCRE (perl)
[英]Convert Perl regular expression to equivalent ECMAScript regular expression
现在,我使用的是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中使用等效的正则表达式,而无需使用第三方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
样式表达式。
是否可以找到将所有Perl正则表达式转换为ECMAScript
样式的通用方法? 有一些工具可以做到这一点吗?
任何帮助将不胜感激!
对于要转换的特定正则表达式,ECMA正则表达式中的等效项为:
/^(\d{3,4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})$/
在这种情况下, \\A
(在Perl regex中)的含义与^
(在ECMA regex中)(匹配字符串的开头)相同, \\Z
(在Perl regex中)与$
(在ECMA regex中)相同的含义(匹配字符串的结尾)。 请注意,如果启用多行模式,则ECMA正则表达式中^
和$
含义将更改为与行的开头和结尾匹配。
ECMA regex是Perl regex的子集,因此,如果该regex使用Perl regex中的专有功能,则可能无法转换为ECMA regex。 即使对于相同的语法,该语法在正则表达式的两个方言之间可能意味着稍有不同,因此检查文档并比较用法总是明智的。
我只想说说ECMA regex和Perl regex有何相似之处。 什么不是相似但可转换,我将尽我所能提起。
ECMA正则表达式缺少与Unicode一起使用的功能,这些功能迫使您查找代码点并将其指定为字符类。
按照有关Perl正则表达式的文档进行操作 :
i
, g
和m
,它们的行为与Perl中的相同。 s
dot-all修饰符可以在ECMA正则表达式中通过使用2个补码字符类来模拟,例如[\\S\\s]
, [\\D\\d]
x
和p
标志。 \\
与非元字符结合使用并不能解决任何特殊含义,我有些怀疑,但是如果您不逃避不需要的地方就没问题了。 .
在ECMA中,排除了另外几个字符。 其余的在ECMA正则表达式中表现相同(甚至m
标志对^
和$
)。 \\a
和\\e
。 \\t
, \\n
, \\r
, \\f
相同。 \\cX
请检查文档-有所不同。 \\xhh
在ECMA regex和Perl regex中很常见(指定2个十六进制数字是最安全的-否则,您将必须查阅文档以查看该语言如何处理少于2个十六进制数字的情况)。 \\uhhhh
是ECMA regex 专有功能,用于指定Unicode字符。 Perl还有其他专用的字符指定方式,例如\\x{}
, \\N{}
, \\o{}
, \\000
。 \\l
, \\u\u003c/code> , \\L
, \\U
是Perl regex 专有的 。
可以通过手动转引引用的部分来模拟\\Q
和\\E
Perl正则表达式中的八进制转义符(少于3个八进制数字)可能会造成混淆。 仔细检查上下文,阅读文档和/或测试正则表达式以确保您了解它在上下文中的作用,因为它可能是转义序列或向后引用。
角色类和其他特殊转义符:
- 如果采用US-ASCII,则
\\w
, \\W
, \\s
, \\S
, \\d
, \\D
在ECMA regex和Perl regex中是等效的。 如果涉及Unicode,事情将变得一团糟。
- ECMA正则表达式中没有POSIX字符类。 使用上面的
\\w
, \\s
, \\d
或在角色类中指定自己。
- 反向引用基本相同-但我不知道它是否允许Perl和ECMA regex的反向引用都超过9。
- 可以使用反向参考来模拟命名参考。
- ECMA regex不支持其余的(
[]
和已提及的转义序列除外)。
断言:
- 关于如何基于
\\w
定义\\b
和\\B
在两种语言中都是等效的。
捕获组:分组()
和反向引用相同。 $n
(在替换字符串中用于反向引用匹配的文本)是相同的。 本节中的其余部分是Perl独有的功能。
引用元字符:(前面部分中已经提到的内容)。
扩展模式:
- ECMA regex不支持在regex内部修改标志。 根据标志的不同,您可能可以重写正则表达式(
s
标志是始终可以在ECMA regex中转换为等效表达式s
标志)。
- 在Perl和ECMA之间,只有
(?:pattern)
(非捕获组), (?=pattern)
(正视), (?!pattern)
(负视)是常见的。
- ECMA正则表达式中没有注释,因此
(?#text)
可以忽略。
- ECMA正则表达式不支持向后看。 Perl支持固定宽度的向后搜索。 在某些情况下,通过在捕获组后面进行查找,可以将用Perl编写的具有正向外观的正则表达式转换为ECMA正则表达式。
- 如前所述,命名模式可以转换为正常捕获组,并可以用编号的反向引用进行引用。
- 其余是Perl独有的功能。
特殊的回溯控制动词:这是Perl独有的,我不知道它们的作用(以前从未接触过它们),更不用说转换了。 最有可能的是它们无论如何都不能转换。
结论 :
如果正则表达式可以充分利用Perl正则表达式的功能,或者在Boost库支持的级别(例如,递归正则表达式)使用,则无法将正则表达式转换为ECMA正则表达式。 幸运的是,ECMA正则表达式涵盖了最常用的功能,因此正则表达式很可能是可转换的。
参考 :
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.