2009-12-07 62 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