在 shell 正则表达式中匹配 ASCII 代码

在 shell 正则表达式中匹配 ASCII 代码

我在 bash 脚本中的正则表达式中匹配 ASCII 代码时遇到了麻烦。

我的有效负载是:payload='#1243669, start 2018-12-17 16:32:50 CET'

我的旧正则表达式是:regold='(#[^,]+),' 我的新正则表达式是:regnew='(#[^\x2c]+)\x2c'

当我在 shell 中进行测试时,它确认新的正则表达式不起作用,而它在 regex101.com 上起作用:

root@test# payload='#1243669, start 2018-12-17 16:32:50 CET'
root@test# regold='(#[^,]+),'
root@test# regnew='(#[^\x2c]+)\x2c'
root@test# if [[ $payload =~ $regold ]]; then echo yes; fi
yes
root@test# if [[ $payload =~ $regnew ]]; then echo yes; fi

编辑:

通过告诉 bash 不支持 PCRE 表达式来部分回答问题。所以我将我的正则表达式移至此:

root@test# regex=$'(\x23[^\x2c]+)\x2c[[:space:]]start[[:space:]][[:digit:]]{4}\x2d[[:digit:]]{2}\x2d[[:digit:]]{2}[[:space:]]([^[:space:]]+)[[:space:]][^\x2c]+\x2c[^\x2c]+\x2c[[:space:]](captureme)'
root@test# pattern='Message #1243669, start 2018-12-17 16:32:50 CET, duration 20, captureme'

同样,我的表达式在 regex101 上效果很好,示例在这里https://regex101.com/r/g4UsUN/1

表达到此为止:... [[:space:]][^\x2c]+ ...但是当我添加 \x2c 时 bash 遇到了一些困难

这是怎么回事 ?

答案1

在 中bash,您可以插入十六进制代码为 的代码的文字字符$'\xHH'bash否则将无法识别字符串中的它们,并且正则表达式[^\x2c]将匹配任何不是\x2或 的字符cregex101.com您测试表达式的网站可能使用了 PCRE 正则表达式引擎。这不是bash用途,它使用 POSIX 扩展正则表达式(该网站似乎不支持)。这也意味着bash不支持您在 PCRE 中使用的其他正则表达式语法,例如\d数字、\s空格字符、前瞻或类似内容。

POSIX 正则表达式(基本的和扩展的)应该在您的系统上记录在re_format(7)手册 ( man 7 re_format) 中,并且还由POSIX 标准

因此,使用

regnew=$'#[^\x2c]+\x2c'

(括号好像没用过,所以我把它去掉了)。由于bash在将字符串分配给变量之前会扩展转义序列,并且由于它们可能扩展为在正则表达式中可能具有特殊含义的字符,因此必须小心转义转义序列以匹配文字值。例如,当要匹配文字点时,可能需要\x2e在(点字符)前面加上\\( )。\\\x2e

bash手册:

该形式的单词$'string'经过特殊处理。该单词扩展为字符串,并按照 ANSI C 标准指定的方式替换反斜杠转义字符。反斜杠转义序列(如果存在)按如下方式解码:

[...]

\xHH

HH其值为十六进制值(一位或两位十六进制数字)的八位字符

请注意,使用$'...'将使 shell 也替换它识别的任何其他转义序列。

相关内容