使用正则表达式,我只需要匹配给定输入字符串中的IPv4子网掩码:
ip=10.0.20.100::10.0.20.1:255.255.254.0:ws01.example.com::off
为了进行测试,此输入字符串包含在一个名为file.txt的文本文件中,但实际的用例将是解析/proc/cmdline,我需要一个解决方案,该解决方案在遇到“ip=”后开始解析、计算字段数和匹配,直到遇到下一白色字符。
我在EL 7.9工作站x86_64上使用bash 4.2.46和GNU grep 2.20来测试表达式。
根据我在其他问题中看到的例子,我提出了下面的grep命令和PCRE正则表达式,它给出的输出非常接近我所需要的。
[user@ws01 ~]$ grep -o -P '(?<!:)(?:\:[0-9])(.*?)(?=:)' file.txt
:255.255.254.0
我对我在这里所做的事情的理解是,我从一个带有“:“字符的负lookbehind开始,试图排除第一个“::“字段,然后是一个非捕获组,以匹配转义的“:“字符,后面是一个数字[0-9],然后是一个带有.*?的捕获组,用于字符串本身的实际匹配,最后是一个前瞻,以查找下一个“:“字符。
问题是,这会给出所需的字符串,但包含一个额外的:字符串开头的字符。
预期输出应如下所示:
255.255.254.0
让我难以理解的是分隔符不一致。字符串中既包含双冒号,也包含单冒号字段,所以我无法简单地匹配分隔符之间的字符串。原因是字段可以有空值。例如
:<null>:ip:gw:netmask:hostname:<null>:off
此处显示的空值表示用户未传递的省略值,用户不需要为预期目的提供该值。
我已经尝试了几种不同的表达方式,就像在其他答案中建议的那样,使用否定的look behinds和look aheads来避免在a开始匹配:其与另一个相邻:
例如,请参阅以下问题:Regular Expression to find a string included between two characters while EXCLUDING the delimiters
如果我可以从第一个冒号开始匹配,它本身不跟在后面,也不跟在前面:字符,同时排除作为分隔符的冒号字符,并继续匹配,直到下一个也不相邻的冒号:并且不包括冒号字符。
我可以通过在表达式中包含“255”来匹配精确的字符串,如下所示:(适用于我们当前的所有使用情形)
[user@ws01 ~]$ grep -o -P '(?:)255.*?(?=:)' file.txt
255.255.254.0
这里的逻辑问题是子网掩码本身可能不总是以“255”开头,但它应该是一个数字,[0-9],这就是为什么我试图在上面的表达式中使用它。为了简单起见,我不需要验证它不大于255。
4条答案
按热度按时间tct7dpnv1#
使用
grep
查看演示here或
输出
gkl3eglg2#
如果这些是分隔符,则您的值应该位于可明确预测的位置。
只需将 every 冒号作为分隔符,然后选择第4个字段。
我不知道你说的是什么意思
让我难以理解的是,分隔符不一致。字符串中既包含双冒号,也包含单冒号字段,所以我无法简单地匹配分隔符之间的字符串。
如果你的分隔符是不可预测和不可解析的,那么它们就毫无用处。如果你的意思是字段可以有引号,也可以没有引号,但是你需要排除引号,我们可以做到这一点。如果双冒号是一种分隔符,而单冒号是另一种分隔符,这是一种糟糕的设计,但我们可能也可以处理这种情况。
对于报价,您需要提供示例。
w8biq8rn3#
使用
gnu-grep
,您可以将模式写为:输出量
说明
(?<!:):
负前瞻,向左Assert非:
,然后匹配:
\K
忽略目前匹配的内容\d{1,3}(?:\.\d{1,3}){3}
匹配4次1-3个数字,以.
分隔(?=:(?!:))
正前瞻,Assert后面没有:
的:
请参见regex demo。
gfttwv5a4#
因为字段的数量总是相同的,只是用“:“分隔,所以你可以使用
cut
。如果你有空字段,这个解决方案也会起作用。