【问题标题】:Why doesn't this regex catch the periods correctly?为什么这个正则表达式不能正确捕获句点?
【发布时间】:2015-08-24 02:51:54
【问题描述】:

我正在努力学习更多关于 shell 脚本的知识。所以,我有一些文件,其中包含 spamassassin 写入目录的电子邮件,我想我会尝试对它们进行一些正则表达式匹配。所以,我选择需要不同匹配的文件,然后尝试对它们进行排序。

我写了这个脚本:

#!/usr/local/bin/bash
#
regex='(\.)?'
files="/var/spool/spam/testing/out.*"
for i in $files; do
domain=`cat $i | grep -i "Message-ID: <" | cut -d'@' -f2 | cut -d'>' -f1 | cut -d' ' -f1`
echo "Domain is $domain"
echo "We're starting the if loop"
if [ -z "$domain" ];
then
echo "Domain is empty"
echo $i
#rm $i
elif ! [[ "$domain" =~ $regex ]];
then
echo "There are no periods in the domainname $domain"
elif [[ $domain =~ $regex ]];
then
echo "There are periods in the domainname $domain"
fi
done

我想要完成的是分离 Message-ID: 的域部分,然后确定该域是什么。一些消息 ID 根本没有域。有些有假域名。有些有这样的域:yahoo.co.uk。

每封邮件都有两个 Message-ID: 条目,因此域名最终会出现两次。

当我在两个文件上运行这个脚本时,我得到的结果是:

# bash /usr/local/bin/rm-bounces.sh 
Domain is xbfoqrka
xbfoqrka
We're starting the if loop
There are periods in the domainname xbfoqrka
xbfoqrka
Domain is SKY-20150201SFT.com
SKY-20150201SFT.com
We're starting the if loop
There are periods in the domainname SKY-20150201SFT.com
SKY-20150201SFT.com

我不明白为什么 xbfoqrka 匹配应该在域名中查找句点的正则表达式,但不匹配在域名中查找 NO 句点的正则表达式。我正在转义句号,所以它应该是完全匹配的,并且 xbfoqrka xbfoqrka 中没有句点。

【问题讨论】:

    标签: regex bash shell match no-match


    【解决方案1】:

    ? 符号表示零或一。所以正则表达式在文本中寻找至少零个或一个.。由于xbfoqrka 中没有.,因此正则表达式会找到匹配项(为零)。

    请注意,对于任意数量的.(零、一、三、100 等),正则表达式将返回 true。这是因为具有 100 个点的字符串至少有零个或一个点。

    【讨论】:

    • 所以我根本不应该使用修饰符?
    • @PaulSchmehl:如果目的仅仅是检测. 的存在,那么正确的正则表达式是'\.'() 在这种情况下也没有用(尽管它们大多是无害的)
    • 你怎么能做到,而且只有一个。两个而且只有两个?
    • 一个且只有一个是:^[^.]*\.[^.]*$ - 基本上,一个以零个或多个非点字符开头的字符串,后跟一个点,后跟零个或多个非点字符(更改如果您想消除以点开头或结尾的字符串,则将它们改为一个或多个)
    • 两个并且只有两个可以作为上述的变体:^([^.]*\.){2}[^.]*$——即,一个字符串以两个零个或多个非点的序列开头,后跟一个点,然后是零或更多非点
    猜你喜欢
    • 1970-01-01
    • 2013-11-05
    • 2013-08-13
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多