正则表达式可选字符串在中间,后跟负展望



我在配置文件中有以下 3 个允许的 ip 条目:日志记录主机 10.1.1.1 日志记录主机 IPv4 10.1.1.2
日志记录主机 10.1.1.3


IPv4 是一个可选字符串。我需要确保没有带有不允许的 ip 的条目。例如:如果有一个行:日志记录主机 10.1.1.4,

则该文件无效,因为 10.1.1.4 不是三个允许的 ip 之一。我想出了一个 Java 正则表达式来检查是否存在任何不允许的 ip:

^logging host (ipv4s)?(?!10.1.1.1|10.1.1.2|10.1.1.3)

仅当可选字符串 ipv4不存在时才有效,而当可选字符串存在时,它才有效,如第二个条目:"日志记录主机 ipv4 10.1.1.2"。第一次尝试中的正则表达式引擎贪婪地匹配"日志记录主机 ipv4",剩余的字符串 10.1.1.2 作为负前瞻条件中的选项之一存在。然后正则表达式引擎进行第二次尝试,仅非贪婪地匹配"日志记录主机",因为 ipv4 是可选的,然后剩余的字符串变为"ipv4 10.1.1.2",这在负前瞻条件下不存在,因此将整行返回为不允许的 ip,这是不正确的。
我错过了什么??

您获得部分匹配,因为您在前瞻后未匹配任何内容。

例如,在logging host 10.1.1.1中,前瞻会看到匹配host后不允许的值,并且没有其他选项可供浏览,因此匹配失败。

logging host ipv4 10.1.1.2将匹配 ipv4 部分。然后,前瞻将看到不允许的匹配项。这次它可以回溯,因为 ipv4 部分是可选的。所以它可以从ipv4之前的位置获得匹配,并且匹配是logging host


您可以将特定 IP 号码的模式缩短为10.1.1.[123]

例如

^logging host (ipv4s)?(?!10.1.1.[123])d{1,3}(?:.d{1,3}){3}$

正则表达式演示

非常感谢"第四只鸟"用他的重要提示引导我找到答案。 总而言之,我需要确保配置文件不应包含任何不允许的日志记录主机条目。以下是配置文件中允许的主机条目:

logging host 10.1.1.1
logging host 10.1.1.2
logging hsot ipv6 EFD7:DEA8:AEE4::11:3

这里的棘手之处在于使用 ipv6 的可选选项由于在可选位置回溯而无法解决问题

^logging host (ipv6s)?(?!10.1.1.1|10.1.1.2|ipv6 EFD7:DEA8:AEE4::11:3)

第一种解决方案使用原子分组来停止回溯,第二种解决方案要简单得多。

^logging (?>host ipv6|host)?s(?!10.1.1.1|10.1.1.2|EFD7:DEA8:AEE4::11:3)  
^logging hosts(?!10.1.1.1|10.1.1.2|ipv6 EFD7:DEA8:AEE4::11:3)

最新更新