带有意外标记的复杂 grep 正则表达式

带有意外标记的复杂 grep 正则表达式

我有一个 Magento 2 安装,我正在尝试查找任何语法不正确的 xml 文件。

我正在尝试使用以下命令在目录中查找code包含标记resource但缺少id属性的节点的任何 acl.xml 文件。

我已经在在线正则表达式测试器上成功测试了此正则表达式代码:

<(?:resource)(?:\s+(?!id\b)[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>

但是,当我尝试使用以下命令时,出现错误:

find app/code -type f -name "acl.xml" | xargs ack '<(?:resource)(?:\s+(?!id\b)[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>'

-bash: syntax error near unexpected token `)'

知道为什么这个命令不起作用吗?

答案1

那里的正则表达式怪物包含单引号,它结束引用的字符串:

find ... '<(?:resource)...(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>'
#        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^  

反斜杠可以转义单引号内的任何内容,因此标记的部分被引号括起来,而其外的内容则没有。如果存在特殊字符,shell 会感到困惑。(好吧,如果我尝试手动解析它,我会感到困惑。)

您至少可以通过改为双引号来解决这个问题,这样反斜杠就可以用来转义字符串中的双引号。

另一种方式是滥用命令替换和此处文档,这样应该能够处理引号而无需进一步转义:

$ string=$(cat <<'EOF'
!"#%&/()[]{}'-.,*
EOF
)
$ echo "$string"
!"#%&/()[]{}'-.,*

相关内容