当使用基础R串的功能,如gsub和grep,是否有任何缺点,因为习惯问题,总是指定perl = TRUE?这有什么缺点吗?
有了perl=TRUE,表达式可以做更多的事情(例如,你可以使用前瞻或后面的断言,或者你可以进行大小写转换\\U),并且性能也更快,正如文档所述.
那么,有什么缺点吗?这perl = TRUE不是默认的向后兼容性吗?当perl = TRUE时,我是否应该注意可移植性问题?
Wik*_*żew 16
将苹果与橙子进行比较并不是一个好主意,因为PCRE正则表达式可以比TRE正则表达式做得更多.虽然它们有着相似的结构,但即使这样,外表也可能会产生欺骗性的结果.
TRE支持文字作为PCRE.文本是任一个普通字符,8位十六进制字符(如\x1B),宽十六进制字符(像\x{263a}),或转义字符:\a,\e,\f,\n,\r,\t.PCRE支持更多:\cx("控制-X",其中x是任何ASCII字符), \0dd(字符八进制代码0dd), \ddd(字符八进制代码ddd,或回参考), \o{ddd..}(字符八进制代码ddd..), \xhh(字符与十六进制代码hh),\x{hhh..}(带十六进制代码的字符hhh..).
两者都有一个.通配符,但在TRE,它匹配任何字符,在PCRE,它只匹配任何字符,但换行字符(S)(和哪些取决于换行符约定PCRE动词, (*CR),(*LF),(*CRLF),(*ANYCRLF),(*ANY)).gsub(".+", "~", "_\n_")会产生~,但gsub(".+", "~", "_\n_", perl=TRUE)会产生~\n~.而相反的例子,使TRE .充当在PCRE,使用(?n)改性剂,gsub("(?n).+", "~", "_\n_")以产生~\n~(绝行结束样式中进行选择).在PCRE模式中,要制作.匹配换行符,您需要在之前使用(?s)内联DOTALL修饰符.(或(?s:.*)类似修饰符组).
两者都支持交替运算符,但由于TRE是文本引导引擎,因此最长的备选方案匹配,而在PCRE中,最左边的选项"胜出".sub("(s|su)", "~", "sub")产量~b(作为su最长的匹配替代品),但sub("(s|su)", "~", "sub", perl=TRUE)产生~ub(因为它s是匹配的第一替代品).
两者都支持反向引用,但TRE仅支持最多9个反向引用.如果您需要10个或更多,请使用PCRE.sub("(.)\\1(.)\\2(.)\\3(.)\\4(.)\\5(.)\\6(.)\\7(.)\\8(.)\\9(.)\\10", "~", "112233445566778899aa", perl=TRUE)将找到一个匹配,没有perl=TRUE,将检测不到匹配.
两者似乎都有类似构造的字符类,[...]但事实上,在TRE所属的POSIX世界中,这些被称为括号表达式.虽然您可以在两者中定义文字字符范围,或者指定它们之间具有OR关系的文字字符,但是不能在括号表达式中使用速记字符类,也不能使用任何转义序列.[\d]+TRE正则表达式中的模式被视为1个或多个反斜杠或/和d字母,而在PCRE模式中,它将被解析为1+个数字(try gsub("[\\d]+", "~", "00\\99d")( - > 00~99~)和gsub("[\\d]+", "~", "00\\99d", perl=TRUE)( - > ~\~d)).这个事实将解释为什么[\]\-\[]+在PCRE模式中匹配1+ ],-或者[在TRE表达式中不需要使用"智能放置",例如[][-].
TRE和PCRE支持\d(数字),\D(非数字),\w("单词"字符),\W("非单词"字符),\s(任何空格),\S(任何非空格)速记字符类.但是,PCRE还支持 \v(任何垂直空白),\V(除垂直空白之外的任何字符),\h(任何水平空格),\H(任何不是水平空格的字符), \N(任何非换行符),\X(任何Unicode字形) ,在处理带有变音符号的字母时很有用),\R(任何Unicode换行符序列).
这两种口味的支持量词,定期,贪婪 ?,*,+,懒惰??,*?,+?,范围/限制量词像贪婪的{3},{8,26}或{3,}与它们慵懒同行?甩在身后.需要注意的是TRE具有限制量词较差的支持(只支持值低于256的{min}量词,并抛出"内存不足"的例外{2557,}和更大的价值.请确保您始终使用0的价值分钟值,如果它是你意味着什么,因为{,2}在实际TRE匹配出现3次.然而,PCRE支持占有欲量词,++,?+,*+,{1,5}+.与他们量化的模式不允许回溯到他们,一旦匹配,发动机从来没有试他们.
这两种风格都支持可以在...... 之间使用的POSIX字符类.但是,TRE支持(字母数字),(字母),(水平空格),(控制字符),(数字),(可见字符,空格和控制字符以外的任何字符),(小写字母),(所有可打印字符),(符号和标点符号),(任何空格),(大写字母)和(十六进制值中的字符).PCRE添加("单词"字符)和(任何ASCII字符).[][:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:][:word:][:ascii:]
两者都支持字边界,但PCRE模式以更可靠的方式实现.参看 gsub("\\b", "~", "CODE")屈服~C~O~D~E~和gsub("\\b", "~", "CODE", perl=T)生产~CODE~.虽然TRE支持特定的前导\<和尾随\>字边界,但PCRE \b仍然更可靠.
两者都支持在模式中使用它们时改变某些模式行为的内联修饰符,例如(?i).TRE支持i(不区分大小写),n(点不再匹配换行符),r(使正则表达式以正确的关联方式而不是正常的左关联方式进行匹配.默认情况下,根据给定的语法,连接在TRE中保持关联状态在Std 1003.1-2001(POSIX)的正则表达式的基本规范中.该标志将连接的关联性翻转为右关联.关联性可以影响匹配如何划分为子匹配,但不会改变整个匹配的内容. regexp)和U(交换贪婪,*?变得贪婪,*变得懒惰).PCRE支持i和U改性剂,以及更多:m(^和$匹配启动/停止的结束行,而不是整个字符串), s(点匹配换行符), x(允许使用空格格式化模式和使用注释), J(允许使用的名称捕获与组相同的名称),X(如果该组合不是有效的正则表达式令牌,则使用反斜杠转义字母为错误),D($仅匹配字符串的最后一端,否则,它也匹配字符串中最后一个尾随换行符之前的位置) )和A(只在字符串的开头匹配,就好像有\A或^在前面).
TRE最明显的缺点是它不支持外观.然而,PCRE可以吹嘘很多东西:
(.{2,})\1+PCRE动词组合在匹配时匹配和跳过模式(*SKIP)(*FAIL) 匹配字符串开头或上一次成功匹配结束的锚点\G 分支重置组允许捕获其中的组以共享相同的ID(?|...|...)和相反的\p{...} Unicode字符属性\P{...})或大写(\L)(\U如果缺少匹配或匹配结束)(实际上,它是使用的PCRE库的扩展)在R)\E匹配重置操作符(\K参考)还有更多的东西,比如锚(\K(字符串的开头),\A(字符串的结尾),\Z(字符串的结尾)),条件"if-then-else"构造,原子分组(与占有量词的工作方式相同,但不允许回溯到整个模式序列中)等.
如果我们想比较R中TRE和PCRE正则表达式引擎的性能,我们应该使用与这两个引擎完全匹配的简单模式.
我主要在Windows中使用R,但是我在Linux VM上安装了R 3.2.3专门用于此测试.MacOS的结果来自t.kalinowski的答案.
让我们\z使用microbenchmark库比较TRE(默认)和PCRE()正则表达式性能(参见R中的更多基准测试选项):
library(microbenchmark)
Run Code Online (Sandbox Code Playgroud)
txt <- "Butterflies are insects in the macrolepidopteran clade Rhopalocera from the order Lepidoptera, which also includes moths. Adult butterflies have large, often brightly coloured wings, and conspicuous, fluttering flight. The group comprises the large superfamily Papilionoidea, which contains at least one former group, the skippers (formerly the superfamily \"Hesperioidea\") and the most recent analyses suggest it also contains the moth-butterflies (formerly the superfamily \"Hedyloidea\"). Butterfly fossils date to the Paleocene, which was about 56 million years ago."
Run Code Online (Sandbox Code Playgroud)
让我们尝试在括号内提取最后一个文本perl=TRUE,这sub是R中非常常见的操作:
# sub('.*\\((.*)\\).*', '\\1', txt)
# => [1] "formerly the superfamily \"Hedyloidea\""
PCRE_1 <- function(text) { return(sub('.*\\((.*)\\).*', '\\1', txt, perl=TRUE)) }
TRE_1 <- function(text) { return(sub('.*\\((.*)\\).*', '\\1', txt)) }
test <- microbenchmark( PCRE_1(txt), TRE_1(txt), times = 500000 )
test
Run Code Online (Sandbox Code Playgroud)
结果如下:
WINDOWS
-------
Unit: microseconds
expr min lq mean median uq max neval
PCRE_1(txt) 163.607 165.418 168.65393 166.625 167.229 7314.588 5e+05
TRE_1(txt) 70.031 72.446 74.53842 73.050 74.257 38026.680 5e+05
MacOS
-----
Unit: microseconds
expr min lq mean median uq max neval
PCRE_1(txt) 31.693 32.857 37.00757 33.413 35.805 43810.177 5e+05
TRE_1(txt) 46.037 47.199 53.06407 47.807 51.981 7702.869 5e+05
Linux
------
Unit: microseconds
expr min lq mean median uq max neval
PCRE_1(txt) 10.557 11.555 13.78216 12.097 12.662 4301.178 5e+05
TRE_1(txt) 25.875 27.350 31.51925 27.805 28.737 17974.716 5e+05
Run Code Online (Sandbox Code Playgroud)
TRE正则表达式仅在Windows中sub获胜,速度超过2倍.在MacOS和Linux上,PCRE()版本以相似的比例获胜.sub
现在,让我们比较不使用回溯的正则表达式的性能,并提取双引号内的单词:
# regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt))
# => [1] "\"Hesperioidea\"" "\"Hedyloidea\""
PCRE_2 <- function(text) { return(regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt, perl=TRUE))) }
TRE_2 <- function(text) { return(regmatches(txt, gregexpr("\"[A-Za-z]+\"", txt))) }
test <- microbenchmark( PCRE_2(txt), TRE_2(txt), times = 500000 )
test
WINDOWS
-------
Unit: microseconds
expr min lq mean median uq max neval
PCRE_2(txt) 324.799 330.232 349.0281 332.646 336.269 124404.14 5e+05
TRE_2(txt) 187.755 191.981 204.7663 193.792 196.208 74554.94 5e+05
MacOS
-----
Unit: microseconds
expr min lq mean median uq max neval
PCRE_2(txt) 63.801 68.115 75.51773 69.164 71.219 47686.40 5e+05
TRE_2(txt) 63.825 67.849 75.20246 68.883 70.933 49691.92 5e+05
LINUX
-----
Unit: microseconds
expr min lq mean median uq max neval
PCRE_2(txt) 30.199 34.750 44.05169 36.151 43.403 38428.2 5e+05
TRE_2(txt) 37.752 41.854 52.58230 43.409 51.781 38915.7 5e+05
Run Code Online (Sandbox Code Playgroud)
最佳平均值属于Linux中的PCRE正则表达式,在MacOS中,差异几乎是疏忽,而在Windows中,TRE的工作速度要快得多.
很明显,TRE(默认)正则表达式库在Windows中的运行速度要快得多.在Linux中,PCRE正则表达式要快得多.在MacOS中,PCRE正则表达式仍然更受欢迎,因为在回溯模式下,PCRE正则表达式在该操作系统中比TRE更快.
| 归档时间: |
|
| 查看次数: |
1119 次 |
| 最近记录: |