2012-03-07 65 views
36

雖然我幾乎可以肯定這已經覆蓋了,我似乎無法找到具體到這樣的東西。當我繼續我的學習狂歡的旅程時,我一直在尋找令我感到困惑的部分,爲什麼事情會以他們的方式發生。使用匹配查找字符串中的子只慶典

搜索並替換或只是字符串匹配的子字符串是最有可能的編寫腳本時,你首先要做的事情之一。但是,試圖堅持單一語言或一組工具在ba​​sh中很難做到,因爲您可以通過多種方式解決大多數問題。我正盡我所能,儘量保持儘可能低的水平與bash。我遇到了一個麻煩,我需要有人向我解釋。

這樣子串與匹配的bash搜索給了我不同的結果取決於正則表達式我用,我不知道爲什麼。

#!/bin/bash 
Stext="Hallo World" 
echo `expr "$Stext" : '^\(.[a-z]*\)'` # Hallo 
echo `expr "$Stext" : '.*World'`  # 11 

雖然這兩個搜索詞,我認爲,既沒有返回他們所發現。爲什麼?

回答

23

兩個表達式是等價的,所不同的是使用正則表達式:

$ echo `expr "$Stext" : '^\(.[a-z]*\)'` 
Hallo 
$ echo `expr "$Stext" : '^.[a-z]*'` 
5 
$ echo `expr "$Stext" : '\(.*World\)'` 
Hallo World 
$ echo `expr "$Stext" : '.*World'` 
11 

正如你所看到的,括號是什麼讓差異要麼返回比賽或比賽本身的長度。

您可以在高級Bash腳本編程指南Chapter 10找到更多的例子。

+0

感謝簡單的解釋@jcollado :)我用你提供的文檔,但不知何故沒有得到這個括號功能。 Bash腳本指南不太容易消化。 – 2012-03-07 08:21:31

+1

由於這個問題是關於[tag:bash],所以更喜歡使用* builtin * regex作爲[@kev建議](http://stackoverflow.com/a/9602260/1765658)而不是* fork到'/ usr/bin/expr' *! – 2015-02-27 23:05:29

49

可以使用BASH_REMATCH變量bash得到匹配的字符串:

$ Stext="Hallo World" 
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH 
Hallo 
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]} 
Hallo 

子字符串的正則表達式中的括號內的子表達式匹配的保存在數組變量BASH_REMATCH。索引爲0的BASH_REMATCH元素是匹配整個正則表達式的字符串部分。索引爲n的BASH_REMATCH元素是匹配第n個加括號的子表達式的字符串部分。

+0

...和'[[「Hello world」=〜^ [^ \] *]] && echo $ {#BASH_REMATCH}' - >'5' ... – 2015-02-27 23:02:31

0

我做這個簡單的功能:

match() { 
    TRUE=1 
    FALSE=0 
    match_return=0 
    echo $1 | grep $2 >/dev/null 
    [ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE 
} 

用法:

match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope" 

整個代碼:https://gist.github.com/TeeBSD/5121b3711fad40a09455

+0

這篇文章與問題或答案沒有實際相關性。 – 2015-03-16 12:32:59

0

爲了快速字符串搜索......一個選項是grep的。
如果沒有找到,返回空,否則匹配:

found=`echo $big | grep -e $short` 

if [ ! -z $found ]; then echo 'There is a match'; else echo 'No no'; fi