使用@s在grep中出现错误行为

问题描述 投票:1回答:1

我正在为nullmailer编写一个小包装器,当我注意到,imho,这是grep中不需要的行为。特别是我注意到@s有些奇怪。

它确实打破了包含@的字符串并将产生错误的输出。

TL; DR

电子邮件地址有一些规则要遵循(E.G.RFC 2822),所以我会为它们使用故意错误的正则表达式,只是为了让事情变得更短。请注意,这不会改变我要求的问题。

我在这篇文章中使用的是电子邮件地址,但问题显然是每个字符串中至少有一个@。

我写了一个小脚本来帮助我解释我“找到”的内容:

#!/bin/bash

funct1() {

  arr=([email protected] [email protected])
  regex="[[:alnum:]]*@[[:alpha:]]*\.[[:alpha:]]\{2,\}"
  for dest in ${arr[@]}; do
    printf "%s\n" "$dest" | grep -o -e "$regex"
  done
}
funct2() {
  arr=([email protected] [email protected])
  regex="[[:alpha:]]*@[[:alpha:]]*\.[[:alpha:]]\{2,\}"
  for dest in ${arr[@]}; do
    printf "%s\n" "$dest" | grep -o -e "$regex"
  done
}

funct3(){
  arr=(local1@[email protected] local2@[email protected])
  regex="[[:alpha:]]*@[[:alpha:]]*@[[:alpha:]]*\.[[:alpha:]]\{2,\}"
  for dest in ${arr[@]}; do
    printf "%s\n" "$dest" | grep -o -e "$regex"
  done
}

funct4(){
  arr=(local1@[email protected] local2@[email protected])
  regex="[[:alpha:]]*@[[:alnum:]]*@[[:alpha:]]*\.[[:alpha:]]\{2,\}"
  for dest in ${arr[@]}; do
    printf "%s\n" "$dest" | grep -o -e "$regex"
  done
}

printf "One @, all parts of regex right:\n"
funct1
printf "One @, first part of regex wrong:\n"
funct2
printf "Two @, first and second part of regex wrong:\n"
funct3
printf "Two @, first part of regex wrong:\n"
funct4
exit 0

为了更好地理解这个问题,我使用了两种类型的字符串:[email protected]local1@[email protected],在我看来,grep的行为方式不正确,字符串至少包含@。

输出是:

One @, all parts of regex right:
[email protected]
[email protected]

One @, first part of regex wrong:
@domain.tld
@domain.tld

Two @, first and second part of regex wrong:

Two @, first part of regex wrong:
@[email protected]
@[email protected]

funct1有一个正则表达式来解决整个字符串,所以没有问题,所有这些都被打印出来。

funct2有一个正则表达式,它只解决从@到最后的字符串,所以我应该期待的是没有输出,因为表达式错误;相反,我所拥有的是字符串的第二部分......

这就是为什么我决定在字符串中添加第二个@并进行一些测试。

funct3只解决了从第二个@到结尾的字符串,所以我应该期待的是因为正则表达式中的错误所以根本没有输出;好的,没有输出。

funct4有一个正则表达式,只解决从第一个@到结尾的字符串,所以我在这里应该期待的是他不能给我任何东西;相反,我所拥有的是第一个@的输出,就像funct2一样。

除了funct1我根本不应该有任何输出,我是对的?

为什么grep会在第一个@中打破结果?

我认为这是一种不受欢迎的行为,因为这样结果将包含完全与我的表达式不匹配的字符串。

我错过了什么吗?

编辑:删除标签undefined-behavior

bash grep undefined-behavior
1个回答
1
投票

你的正则表达式有问题,按设计工作。您也可以将@的数量计算为测试。我个人会创建一个像这样的布尔方法:

#!/bin/bash

# -- is email address valid ? --    
function isEmailValid() {
      echo "$1" | egrep -q "^([A-Za-z]+[A-Za-z0-9]*((\.|\-|\_)?[A-Za-z]+[A-Za-z0-9]*){1,})@(([A-Za-z]+[A-Za-z0-9]*)+((\.|\-|\_)?([A-Za-z]+[A-Za-z0-9]*)+){1,})+\.([A-Za-z]{2,})+"
}


if isEmailValid "_#@[email protected]" ;then
        echo "VALID "
else
        echo "INVALID"
fi


if isEmailValid "[email protected]" ;then
        echo "VALID "
else
        echo "INVALID"
fi

或者更简单:

function isEmailValid() {
      regex="^([A-Za-z]+[A-Za-z0-9]*((\.|\-|\_)?[A-Za-z]+[A-Za-z0-9]*){1,})@(([A-Za-z]+[A-Za-z0-9]*)+((\.|\-|\_)?([A-Za-z]+[A-Za-z0-9]*)+){1,})+\.([A-Za-z]{2,})+"
      [[ "${1}" =~ $regex ]]
}
© www.soinside.com 2019 - 2024. All rights reserved.