为啥这个正则表达式不生成匹配?

Posted

技术标签:

【中文标题】为啥这个正则表达式不生成匹配?【英文标题】:Why doesn't this regular expression generate a match?为什么这个正则表达式不生成匹配? 【发布时间】:2016-03-03 16:54:32 【问题描述】:

我有以下配置文件:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth           sufficient      pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
#auth           required        pam_wheel.so use_uid
auth            substack        system-auth
auth            include         postlogin
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet
account         include         system-auth
password        include         system-auth
session         include         system-auth
session         include         postlogin
session         optional        pam_xauth.so

这些空格似乎是制表符。在 vim 中打开列表 (:set list) 显示:

#%PAM-1.0$
auth^I^Isufficient^Ipam_rootok.so$
# Uncomment the following line to implicitly trust users in the "wheel" group.$
#auth^I^Isufficient^Ipam_wheel.so trust use_uid$
# Uncomment the following line to require a user to be in the "wheel" group.$
#auth^I^Irequired^Ipam_wheel.so use_uid$
auth^I^Isubstack^Isystem-auth$
auth^I^Iinclude^I^Ipostlogin$
account^I^Isufficient^Ipam_succeed_if.so uid = 0 use_uid quiet$
account^I^Iinclude^I^Isystem-auth$
password^Iinclude^I^Isystem-auth$
session^I^Iinclude^I^Isystem-auth$
session^I^Iinclude^I^Ipostlogin$
session^I^Ioptional^Ipam_xauth.so$

我要匹配就行了:

#auth           required        pam_wheel.so use_uid

整行匹配不起作用。我不知道为什么......猜测它与空格标签有关:

grep "#auth           required        pam_wheel.so use_uid" /etc/pam.d/su

(返回不匹配)

所以,我认为值得尝试通过以下方式进行匹配:

grep "#auth\s+required\s+pam_wheel.so\s+use_uid" /etc/pam.d/su

我将这个正则表达式读作“#auth”,后跟至少一个或多个制表符/空格,然后是“必需”,然后是至少一个或多个制表符/空格,然后是“pam_wheel.so”等。 .

但是,这也不匹配。我不确定这里出了什么问题。我错过了什么?

【问题讨论】:

grep 正则表达式不支持\s 转义序列。如果您使用的是 GNU grep,请使用 -P 选项来使用 PCRE 正则表达式。 你也应该在 "pam_wheel.so" -> "pam_wheel\.so" 中转义句号 【参考方案1】:

您可以在匹配空格或制表符的正则表达式中使用[[:blank:]]

grep '#auth[[:blank:]]*required[[:blank:]]*pam_wheel\.so[[:blank:]]*use_uid' /etc/pam.d/su

#auth       required    pam_wheel.so use_uid

【讨论】:

记得转义句号以防万一。【参考方案2】:

使用扩展正则表达式

默认情况下,grep 使用基本正则表达式 (BRE) 引擎。如果您希望扩展正则表达式引擎 (ERE) 支持字符类快捷方式,例如 \s,那么您需要运行 egrepgrep -E。例如:

$ egrep "#auth\s+required\s+pam_wheel\.so\s+use_uid" /etc/pam.d/su
#auth       required    pam_wheel.so use_uid

或者,您可以使用 grep 和通过 grep -Ppcregrep 内置的兼容 Perl 的正则表达式 (PCRE) 库。但是,并非所有平台都支持此功能。

参考文献

man 7 re_format 了解有关 BRE 和 ERE 之间差异的更多详细信息。 man 3 pcre 了解有关 PCRE 库和语法的信息。

【讨论】:

谢谢你们。但是,它也不匹配任何一个已发布的表达式。我觉得这可能是一些不可见的字符、编码或我忽略的其他一些特征。如果我要从文件中复制该行,将其粘贴到 echo 命令中,然后通过 grep 将其发送到表达式匹配: $ echo "#auth required pam_wheel.so use_uid" | \ egrep "#auth\s+required\s+pam_wheel\.so\s+use_uid" #auth required pam_wheel.so use_uid 但是,当我将整个文件输入 grep 时,完全相同的表达式会失败。【参考方案3】:

谢谢。我没有意识到我需要使用扩展表达式,并且没有转义。

【讨论】:

以上是关于为啥这个正则表达式不生成匹配?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个正则表达式模式不匹配? [复制]

为啥这个重复的内部组在正则表达式中不匹配? [复制]

Qt正则表达式 如何得到字符串中所有满足条件的字符。这个正则为啥匹配不成功

为啥这个正则表达式匹配?

正则表达式.+可以匹配空格,但是[.\w]+却不匹配,为啥?

正则表达式不匹配,不知道为啥[重复]