2009-08-08 28 views
4

我從我正在翻譯成Python的腳本中獲取這段Perl代碼片段。我不知道這是什麼!「操作員在做;某種正則表達式替換。不幸的是,對於像這樣的操作符搜索Google或Stackoverflow並不會產生很多有用的結果。什麼是「s!」在Perl中的運算符呢?

$var =~ s!<foo>.+?</foo>!!; 
$var =~ s!;!/!g; 

每行是幹什麼的?我想知道如果我再次遇到這個操作員。

而且,Python中的等效語句是什麼?

回答

15

s!foo!bar!與更常見的s/foo/bar/相同,只是foo和bar可以包含未轉義的斜槓而不會造成問題。它所做的是,它用bar代替了正則表達式foo的第一次出現。帶有g的版本將替換所有發生的事件。

+1

Perl借鑑了很多語言。它從sed借了這個。 – runrig 2009-08-09 01:50:07

2

s是替換運算符。通常,這使用「/」爲分隔符:

s/foo/bar/ 

,但是這不是必需的:許多其它字符可用於作爲分隔符來代替。在這種情況下, '!'已被用作分隔符,大概是爲了避免需要在實際文本中替換「/」字符。

在您的具體情況下,第一行刪除文本匹配'。+?';即它刪除帶有或不帶內容的'foo'標籤。

第二行代替所有';'帶有'/'字符的字符,全局(全部出現)。

蟒蛇相當於代碼使用re模塊:

f=re.sub(searchregx,replacement_str,line) 
+0

「...它刪除帶有或不帶內容的'foo'標籤。」不完全 - 它刪除至少包含一個*字符的'foo'標籤。 +1,但是,實際上顯示一些pythonic代碼。 – pilcrow 2009-08-09 02:16:17

+0

@pilcrow:恩,謝謝你的澄清。 '?'這裏似乎是多餘的。我假設'。+?'會像'(。+)?'一樣工作。但事實並非如此。 – 2009-08-09 08:01:37

+0

'。+?'意思是「一個或多個,但儘可能少但仍然可以匹配」。與'。+'相比,儘可能匹配。 – sepp2k 2009-08-10 20:56:10

13

它做完全一樣$var =~ s///。即在$var變量內執行搜索和替換。

在Perl中,您可以在s後面定義分隔符。爲什麼?因此,例如,如果您匹配'/',則可以指定另一個分隔字符(在本例中爲'!'),而不必轉義或反向匹配您匹配的字符。否則,你會最終與(說)

s/;/\//g; 

這是有點混亂。

Perlre有更多相關信息。

0

與python等價的是使用re模塊。

3

s是替代運算符。通常它的形式是s/foo/bar/,但是你可以用一些其他字符替換//分隔符字符,如。使用其他分隔符字符可能使得像路徑這樣的事情更容易處理,因爲您不需要轉義路徑分隔符。

有關更多信息,請參閱manual page

你可以在re-module找到類似的python功能。

10

Perl允許您爲許多構造選擇分隔符。這使得它更容易看到什麼是在表達式會像

$str =~ s{/foo/bar/baz/}{/quux/}; 

正如你可以看到,並不是所有的分隔符具有相同的效果。包圍字符(<>,[],{}())在開始和結束時使用不同的字符。而?用作正則表達式的分隔符時,會使正則表達式在對reset()運算符的調用之間僅匹配一次。

閱讀perldoc perlop(特別是關於m/PATTERN/msixpogc?PATTERN?s/PATTERN/REPLACEMENT/msixpogce的章節)可能會有幫助。

2

s!是「合適的」s///操作員的句法糖。基本上,你可以替換你想要的任何分隔符而不是'/'。

至於每一行是幹什麼的,第一行是匹配正則表達式<foo>.+?</foo>的發生,並用全部內容替換整個區塊。第二個匹配正則表達式;並用/替換它。

s///是替代運營商。它需要一個正則表達式和一個替換字符串。

s/regex/replace string/; 

它支持大多數正常的正則表達式的開關,其被以正常的方式使用(由它們附加到操作者的端部)的(所有?)。