grep -P

pattern is a Perl regular expression. Based on PRCE. (兼容Perl的正则表达式包)

  • 八进制
1
echo -e 'a\nb' | grep -z -P 'a\012b'
  • 十六进制
    • \xFF
    • \x{…}
1
echo -e 'a\nb' | grep -z -P 'a\x{0A}b'
  • 元字符 . 不能匹配换行符, 其他 Unicode 换行符等可以匹配
  • \w 严格等价于 [a-zA-Z0-9_], java , PHP 也是一样的, 但是 Perl 语言的正则引擎室支持 Unicode 字符(未验证)

grep -E / egrep

  • 不支持八进制、十六进制转义表示

  • 元字符 . 可以匹配换行符(\n), Unicode 换行符 NEL (\u0085), Unicode 行分隔符 LS (\u2028), Unicode 段分隔符 PS (\u2029)

  • \w 可以匹配汉字

1
echo 'a严b' | grep -z -E 'a\wb'

对于字符组, 尤其是排除型字符组,都支持 \n, \r, Unicode 换行符,行分隔符,段分隔符都支持

Notepad++

Notepad++ 的 匹配新行模式, 应该是启用了 点通配符模式 - dotALL(Perl中的单行模式), 以及 多行模式 - 行锚点可以匹配行内的换行符前后的位置

POSIX 规定,点号不能匹配 NUL (值为0的字符), 具体工具可有有差异。

grep: PCRE does not support \L, \l, \N{name}, \U, or \u

PCRE(包括PHP), java.util.regex \w 严格等价于 [a-zA-Z0-9_]

java.util.regex

  • \w 严格等价于 [a-zA-Z0-9_]

  • \s 不匹配 Unicode 换行符

  • 普通模式下 . 不能匹配 \n, \r, Unicode 换行符 NEL (\u0085), Unicode 行分隔符 LS (\u2028), Unicode 段分隔符 PS (\u2029)

  • 字符组可以匹配换行符,包括 Unicode 的上述行终结符

  • 支持字符组的计算 [[a-c]&&[a-z]] [[a-c]OR[d-e]], 当然也可以使用环视来实现

  • 多行模式下(?:m),锚点可以匹配 Unicode 行终结符 Page.370

  • $ 既可以匹配目标字符串的末尾,也可以匹配整个字符串末尾的换行符之前的位置 (这里的换行符也包括Unicode 的行终结符)

  • \Z 和普通模式下的 $ 的意义一样

  • \z 只匹配文本的末尾的位置

  • \A 总是与普通的 ^ 一样

  • \b 单词分界符 与 \B 非单词分界符对单词字符的定义仅限于 ASCII 字符,如果需要扩展,可以使用环视功能以及 Unicode 属性实现

1
(?<!\pL)(?=\pL)......(?<=pL)(?!\pL)
  • 正则表达式中设定匹配模式,支持

    • (?i)...(?-i), (?i) 开启模式,(?-i)关闭模式
    • (?:(?i)very), (?i) 的作用范围只限于括号內部,闭括号后就失效
    • 支持模式修饰范围,(?i:...)
  • 文字文本模式(消除所有元字符的特殊含义进行匹配), java.util.regex 的引擎支持 \Q...\E 序列,但是它只会消除除了 \E 之外的所有的元字符的特殊含义,直接在字符串两边加上,会有问题(原始字符串出现 \E, 会截断,只对前面的部分应用该模式)。请直接使用 Pattern.quote 方法或自己写一个处理方法。

Perl 中的锚点都不支持 Unicode 行终结符, 而 Java 的普通模式下的 $ 以及多行模式下的 ^ 以及 $ 都支持 Unicode 行终结符。

基于 PCRE 的 grep -P 测试, 普通模式下,$ 只匹配末尾,不匹配换行符之前的位置