2011-05-13 34 views
1

我需要一個正則表達式,可以提取由相同的非字母字符包圍的兩個數字的任意組,如從字符串中提取「02」 my_file_name-02-and_some」正則表達式(sed)如何1轉義特殊字符和2組它們

這是據我得到:

echo 'my_file_name-02-and_some' | sed 's/.*[-_]\([0-9][0-9]*\)[-_].*/\1/g'

產生

02(唷,二小時+對於結果),但

echo 'my_file_name-002-and_some' | sed 's/.*[-_]\([0-9][0-9]*\)[-_].*/\1/g'

產生

002所以它不是真正的工作:(。我也希望它匹配「my_file_name(02)和_some」和其他可能的周圍字符,想法是這兩個周圍的字符必須是相同的..?天哪,我的頭疼。

恐怕,鑑於上下文,這是一個sed正則表達式。

+0

所以呢? 00,還是一無所有? – Eduardo 2011-05-14 00:29:49

+0

在第二種情況下,不應返回任何內容。 – yPhil 2011-05-15 10:41:21

回答

2

周圍相同的字符:

twonum=`echo 'my_file_name-00-andsome' | sed 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/'` 

會產生00記住,你可以在LHS使用反向引用過。

sed 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/' 
      ^this is 1st  ^that's \1 mean: THE SAME as in 1st \(...\) group 

添加匹配[]和()可以在第二種情況下有什麼預期的結果使用這一個(不是很好,但希望工作)

sed 's/^.*\(.\)\([0-9][0-9]\)\1.*$/\2/;s/^.*(\([0-9][0-9]\)).*$/\1/;s/^.*\[\([0-9][0-9]\)\].*$/\1/' 
+0

是的,這就是喬莫!這正是我想要的:周圍的字符被分組:)剩下的唯一問題是括號和括號被忽略(因爲非常自然),所以'echo'my_file_name [00]和some'| sed's /^.* \(。\)\([0-9] [0-9] \)\ 1。* $/\ 2 /''不匹配任何東西:( 我認爲它值得另一個問題... – yPhil 2011-05-15 10:40:11

+0

究竟哪個部分能夠識別周圍人物的性質? – yPhil 2011-05-15 10:45:19

1

這將是您的問題:

([0-9][0-9]*) 

如果你只是想兩個數字,那麼你不需要*,這意味着「0個或更多的在我之前有什麼」。這就是爲什麼它匹配002

+0

啊,謝謝onteria_;以及關於匹配特殊字符,並將它們分組,以便我可以確定它們是相同的? – yPhil 2011-05-14 00:46:52

+0

事實上,我沒有意識到如何在bash提示符下正確測試sed regexp;因爲如果未找到匹配項,bash將返回完整的字符串: 'echo'my_file_name-002-and_some'| sed's /.* [-_] \([0-9] [0-9] \)[-_]。*/\ 1/g''將產生 'my_file_name-002-and_some',意味着你的正則表達式實際上起作用,如果你輸入: 'echo'my_file_name-02-and_some'| sed's /.* [-_] \([0-9] [0-9] \)[-_]。*/\ 1/g''你得到一個不錯的 '02'但它實際上意味着你的正則表達式失敗。 這可能會引起混淆。 – yPhil 2011-05-14 00:51:43

+0

@xaccrocheur我有點時間來測試完整的代碼,但我會這樣做的基本方法是:'(。[0-9] [0-9]。)'這將組2位數字前後的字符。然後,我會用一些bash來檢查第一個和最後一個字符,看它們是否相同。 – 2011-05-14 00:56:41