首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用POSIX BRE/ERE regex将IP地址提取为整字

使用POSIX BRE/ERE regex将IP地址提取为整字
EN

Stack Overflow用户
提问于 2017-06-20 21:43:03
回答 2查看 17.3K关注 0票数 5

我正在尝试通过正则表达式来匹配在traceroute输出中找到的IP地址。我不会尝试验证它们,因为假设traceroute是有效的(即不输出像999.999.999.999这样的东西)是足够安全的。我正在尝试以下正则表达式:

代码语言:javascript
复制
([0-9]{1,3}.?){4}

我正在regex101中测试它,它确实验证了一个IP地址。然而,当我尝试

代码语言:javascript
复制
echo '192.168.1.1 foobar' | grep '([0-9]{1,3}.?){4}' 

我什么也得不到。我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-20 21:49:22

您使用了POSIX模式,但是没有通过-E选项让grep使用POSIX风格。因此,grep改用POSIX BRE,您需要转义{n,m}量词和(...),以便将它们解析为特殊的正则表达式运算符。

注您需要对.进行转义,以便它只能与文字点匹配。

要使您的模式以您想要的方式与grep一起工作,您可以使用:

代码语言:javascript
复制
grep -E '([0-9]{1,3}\.?){4}'      # POSIX ERE
grep '\([0-9]\{1,3\}\.\?\)\{4\}'  # POSIX BRE version of the same regex

请参见online demo

然而,这个正则表达式也将匹配几个数字的字符串,因为.是可选的。

您可以通过如下方式展开模式来解决此问题

代码语言:javascript
复制
grep -E '[0-9]{1,3}(\.[0-9]{1,3}){3}'      # POSIX ERE
grep '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' # POSIX BRE

参见another demo

基本上,它匹配:

  • [0-9]{1,3} -1到3次出现任何ASCII digit
  • (\.[0-9]{1,3}){3} -3出现:
    • \. -a文字.
    • [0-9]{1,3} -1到3次任何ASCII digit

要确保仅匹配有效的IP,您可能需要使用more precise IP matching regex

代码语言:javascript
复制
grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\b' # POSIX ERE

参见this online demo

您可以进一步调整它与单词边界(可以是\< / \>\b),等等。

-o选项与grepgrep -oE 'ERE_pattern' file / grep -o 'BRE_pattern' file一起使用来提取IP。

票数 10
EN

Stack Overflow用户

发布于 2018-07-30 07:11:55

要进行更有效的验证,最好使用函数而不是简单的正则表达式匹配:

代码语言:javascript
复制
#!/bin/bash
is_valid_ip() {
  local arr element
  IFS=. read -r -a arr <<< "$1"                  # convert ip string to array
  [[ ${#arr[@]} != 4 ]] && return 1              # doesn't have four parts
  for element in "${arr[@]}"; do
    [[ $element =~ ^[0-9]+$ ]]       || return 1 # non numeric characters found
    [[ $element =~ ^0[1-9]+$ ]]      || return 1 # 0 not allowed in leading position if followed by other digits, to prevent it from being interpreted as on octal number
    ((element < 0 || element > 255)) && return 1 # number out of range
  done
  return 0
}

您可以像这样调用它:

代码语言:javascript
复制
while read -r ip; do
  is_valid_ip "$ip" && printf '%s\n' "$ip" 
done < <(your command that extracts ip address like strings)

相关信息:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44654809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档