2009-12-07 60 views
1

我需要一些方法来查找包含字符和数字,但恰好只有4位的任何组合的话,和至少一个字符。grep的正则表达式4位

例:

a1a1a1a1  // Match 
1234   // NO match (no characters) 
a1a1a1a1a1  // NO match 
ab2b2   // NO match 
cd12   // NO match 
z9989   // Match 
1ab26a9   // Match 
1ab1c1   // NO match 
12345   // NO match 
24    // NO match 
a2b2c2d2  // Match 
ab11cd22dd33 // NO match 
+0

为什么不是“1234”?它正好有4位数字。你需要更精确地了解你的要求。 – 2009-12-07 23:50:21

+0

我的意思是字符和数字(两字符位数) 猫测试 ab2b2 CD12的任意组合 z9989 1ab26a9 1ab1c1 a2b2c2d2 ab11cd22dd33 有效的输出应该是 a2b2c2d2 z9989 1ab26a9 – Leo 2009-12-09 11:55:35

回答

0

随着grep

grep -iE '^([a-z]*[0-9]){4}[a-z]*$' | grep -vE '^[0-9]{4}$' 

用Perl做在一个模式:

perl -ne 'print if /^(?!\d{4}$)([^\W\d_]*\d){4}[^\W\d_]*$/' 

时髦[^\W\d_]字符类是拼[A-Za-z]一个世界性的方式:它捕捉所有字母,而不仅仅是英文lish的。

0

假设你只需要ASCII,而你只能访问的grep的(相当原始的)正则表达式构造,下面应该是八九不离十:

grep ^[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*[a-zA-Z]*[0-9][a-zA-Z]*$ | grep [a-zA-Z] 
0

你可以尝试

[^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]* 

但这将匹配1234.为什么这不符合你的标准?

3

以匹配grep的一个数字,您可以使用[0-9]。要匹配除数字之外的任何内容,可以使用[^ 0-9]。由于可以是任意数量的字符,所以您可以添加一个“*”(前面的任何数字)。所以你会希望在逻辑上是

(anything not a digit or nothing)* (any single digit) (anything not a digit or nothing)* . ...

,直到你有4个“任何一个数字”组。即[^ 0-9] * [0-9] ...

我发现与grep长模式,尤其是长字符串需要逃脱的特殊字符,最好慢慢建立,所以你是确定你明白发生了什么事。例如,

#this will highlight your matches, and make it easier to understand 
alias grep='grep --color=auto' 
echo 'a1b2' | grep '[0-9]' 

会告诉你它是如何匹配的。然后,您可以在理解每个部分后扩展该模式。

0

该正则表达式是:

([A-Za-z]\d){4} 
  • [A-ZA-Z] - 为字符类
  • \ d - 对数
  • 你wrapp它们在()将它们组表示格式字符按照编号
  • {4} - 表示它必须是4次重复
2

我不确定您可能采取的所有其他输入(即是ax12ax12ax12ax12有效吗?),但是这将工作根据您发布的内容:

%> grep -P "^(?:\w\d){4}$" fileWithInput 
+0

你可能希望在某些情况下使用'\ b'字边界而不是BOL(^)和EOL($)。 – 2009-12-07 22:29:09

+0

@丹尼斯。好点子。我正在写它来匹配他给出的输入,但是如果每行有多个单词,那么是的,我应该使用\ b来代替^和$。 – 2009-12-07 22:36:28

1

如果你不介意使用一个小壳,以及,你可以做这样的事情:

echo "a1a1a1a1" |grep -o '[0-9]'|wc -l 

这将显示在字符串中找到的位数。如果你喜欢,你可以再测试匹配的给定数量:

max_match=4 
[ "$(echo "a1da4a3aaa4a4" | grep -o '[0-9]'|wc -l)" -le $max_match ] || echo "too many digits." 
0

您可以正常使用shell脚本,无需复杂的正则表达式。

var=a1a1a1a1 
alldigits=${var//[^0-9]/} 
allletters=${var//[0-9]/} 
case "${#alldigits}" in 
    4) 
    if [ "${#allletters}" -gt 0 ];then 
     echo "ok: 4 digits and letters: $var" 
    else 
     echo "Invalid: all numbers and exactly 4: $var" 
    fi 
    ;; 
    *) echo "Invalid: $var";; 
esac 
+0

actualy我写的剧本:) #/斌/庆典 回声 “$ @” |!TR -s “” “\ n” 个S >>排序 猫分类|同时tostr 读做 L = $( echo $ tostr | tr -d“\ n”| wc -c) temp = $(echo $ tostr | tr -d az | tr -d“\ n”| wc -c) if [$ temp -eq 4 ];然后 if [$ l -gt 4];然后 printf“%s”“$ tostr” fi fi done echo – Leo 2009-12-09 13:09:13

0

谢谢您的回答 finaly我写了一些剧本,它的工作完美: 。/P ab2b2 cd12 z9989 1ab26a9 1ab1c1 1234 24 a2b2c2d2

#!/bin/bash 
echo "[email protected]" |tr -s " " "\n"s >> sorting 
cat sorting | while read tostr 
do 
    l=$(echo $tostr|tr -d "\n"|wc -c) 
    temp=$(echo $tostr|tr -d a-z|tr -d "\n" | wc -c) 

    if [ $temp -eq 4 ]; then 
    if [ $l -gt 4 ]; then 
     printf "%s " "$tostr" 
    fi 
    fi 
done 
echo