2012-06-05 174 views
1
sed "s/\(^[a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2 \1/g" desired_file_name 

我apreciate它,即使你只以免用言語結構也解釋了它或部分在s\alphanumerical_at_start\something\alphanumerical_at_end\something_else\global是什麼正則表達式的意思是,爲什麼

有人能解釋一下這是什麼意思,爲什麼,是所有regEx如此...可怕?

我知道它會用最後一個替換第一個小寫字母數字字。但是,你能解釋一下這裏發生了什麼事嗎?所有/\\(.*\)\以及其他所有內容都是什麼?

我只是迷路了。

編輯:以下是我所得到的:(^[a-z0-9]*)開始於低谷z和0低谷9;和[a-z,0-9]*$是相同的,但最後一個字(但[0-9,a-z] =只是前2個字符/第一個字符,或整個字?)。另外:*\(.*\)\甚至意味着什麼?

+1

*「爲什麼和所有regEx都這麼...糟糕」*不能成爲您的嚴重問題。事情並不會因爲他們逃避理解而自動變得糟糕。 – Tomalak

+0

Lol @「你的理解水平」,沒有ofc不是(我在這裏學習畢竟),他們是可怕的,因爲......看着它。這是100%排斥。舉例來說,我認爲python代碼看起來很神奇(因爲它很容易閱讀),而C++則不太吸引人(雖然沒那麼糟糕)。另一方面,這聳聳肩*。但如果你沒有有用的評論,請不要評論在第一位,謝謝:) – Kalec

+1

我不覺得正則表達式令人厭惡。我發現它們優雅而美麗。 –

回答

2

這是一個sed搜索和替換,其格式爲s/search/replace/flags,唯一的標誌是g,這意味着搜索/替換是全局的,所以如果匹配在一行而不是僅在第一行發生多次。

首先,這裏是它搜索正則表達式:

\(^[a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\) 

或者更可讀的格式:

\(   # start capture group 1 
^   # match at the beginning of the line 
    [a-z,0-9]*  # zero or more alphanumeric or comma characters (lowercase only) 
\)    # end capture group 1 
\(   # start capture group 2 
    .*    # zero or more of any character (except for newlines) 
\)    # end capture group 2 
\(   # start capture group 3 
    [ ]   # literal ' ' character (I added brackets for clarity) 
    [a-z,0-9]*  # zero or more alphanumeric or comma characters (lowercase only) 
    $    # match at the end of the line 
\)    # end capture group 3 

這裏被替換:

\1\2 \1 

這將取代整條線(因爲^$錨在正則表達式)與捕獲組1的內容,然後是捕獲組2的內容,然後是空格,然後是捕獲組1的內容。

+1

你能解釋爲什麼我們需要避開括號?我知道我們需要,但我不知道爲什麼,所以我問。 – nhahtdh

+0

[]爲''提供了極大的幫助。我只需要澄清一些問題:[0-9,a-z]代表一個符合這些標準的整個單詞,直到出現空白爲止? – Kalec

+0

[0-9,a-z]僅匹配單個字符。需要[0-9,a-z] *爲任意數量的字符,直到空格 – solidau

1
  • (^ [AZ,0-9]) - (。) - 任意字符(第2組)
  • (即[az,0在一行的開始(第1組)
  • 字母數字或逗號-9] * $) - 一個空格,後跟0或更多的字母數字或逗號[猜逗號只是一個錯誤],到行尾
  • \ 1 \ 2 \ 1 - 替換爲(group 1)(組2)空間(組1)
  • g - 在輸入中無處不在
+0

\ 1 \ 2 \ 1我還是不明白。用什麼替換什麼。和'\(。* \)\'對於我來說是最困惑的 – Kalec

+0

'\ 1' - 在正則表達式中是一個反向捕獲(group):/(w +)0 \ 1 /是一個每個單詞,它有這個模式'part0part' – gaussblurinc

+0

@Alexander:有幾個反斜槓和星號沒有出現在問題中,因爲OP沒有使用StackOverflow出色的代碼格式功能。再次檢查,並請自己使用代碼格式。 –

1

正則表達式是一種描述常規語法的方法。他們以非常簡潔和高效的方式完成此任務。這使他們看起來很複雜。

它們也是結構化的和可解碼的。

首先,有一個sed調用。

sed "{operation}/{expression}/{replacement}/{modifiers}" {argument} 

  • sed與斜線的部分分離出來。這意味着您不能在{expression}{replacement}中有未轉義的正斜槓。
  • 與其他大多數正則表達式小號不同,sed使用括號來匹配實際的括號,並使用轉義括號來定義捕獲組。

{operation}恰好是s - 替代。

{expression}\(^[a-z,0-9]\)\(.*\)\([a-z,0-9]*$\),其分解爲

 
\(   # start capture group 1 
^   # match the start of the string 
    [a-z,0-9] # match characters a-z and 0-9 and a comma (!) 
\)    # end capture group 1 
\(   # start capture group 2 
    .*   # match any character (.), zero or more times (*) 
\)    # end capture group 2 
\(   # start capture group 3 
       # match a space 
    [a-z,0-9]* # match characters a-z and 0-9 and a comma (!) 
    $   # match the end of the string 
\)    # end capture group 3 

試想想了一秒鐘,它會是多少碼(和時間)帶你來寫,做同樣的功能,以及如何小空間正則表達式需要。這就是爲什麼它很難閱讀 - 這是非常壓縮。

{replacement}\1\2 \1\n被稱爲回參考,其中n是捕獲組的數目。因此,這再次插入組1和組2的內容,組1的內容。

{modifiers}部分是g標誌,這使得正則表達式應用盡可能經常。在這種特殊情況下,由於上面的正則表達式只能匹配一次,所以沒什麼意義。

+1

如果'operation'是替換之外的東西,語法將會不同,並且不會有'expression'和'replacement'。所以我會開始用'/表達式}/{替換}/{修飾符}'來解釋。無論如何,很好的答案。 –

+0

@Lev:沒錯,我只是想盡可能地分開各個部分。 – Tomalak

+1

有點回歸,但爲了證明Tomalak提出的關於代碼和時間來編寫正則表達式可以實現的功能的觀點,這個問題(http://uva.onlinejudge.org/external/100/10058.html)可以可以在正則表達式的幫助下在(clean)Java代碼的20個LOC內解決,但是在純C中需要更多的時間和代碼。 – nhahtdh

1
s/\(^[a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2 \1/g 

s -> substitute 
/-> begin of regex 
\(-> begin of a first field(accessed as \1 later) 
^ -> from the begining of line in data 
[a-z,0-9] -> list of characters which will be compared, lowercase a through z, comma, and 0 through 9 
* -> zero or more times 
\) -> end of \1 field 
\(-> begin of \2 
.* -> . means any character. .* means any character zero or more times 
\) -> end of \2 
\([a-z,0-9]*$ -> begin of \3, followed by a space, follwed by zero or more a-z, comma, 0-9 
\) -> end of \3 field 
/-> end of regex to replace 

/-> begin of regex to replace with 
\1\2 \1 -> first field followed by second field followed by a space and again the first field 
/-> end of regex to replace with 

g -> globally 
相關問題