![](/img/trans.png)
[英]Negative RegEx pattern matching in Python equivalent to Perl(!~ operator)
[英]Perl pattern matching in Python
我是Perl用戶多年,最近才開始使用Python。
我了解到總是有“一種明顯的方法”來做某些事情。 我希望檢查“一種”方法,將下面的Perl中的編碼樣式轉換為Python。 謝謝!
目的是:
Perl:
if ($str =~ /my(pat1)and(pat2)/) {
my ($var1, $var2) = ($1, $2);
}
據我為Python所學,下面是我現在的編碼方式。 它似乎比Perl采取了更多的步驟。 這就是為什么我對我的Python代碼有疑問的原因。
mySearch = re.search ( r'my(pat1)and(pat2)', str )
if mySearch:
var1 = mySearch.group(1)
var2 = mySearch.group(2)
Python不像perl那樣優先考慮模式匹配和字符串操作。 這些是類似的模式,是的,Python更長(它還有很多很棒的東西,例如它是OOP,並且沒有使用怪異的神奇全局變量)。
出於記錄,您可以使用元組拆包來使其更加簡潔:
var1, var2 = mySearch.groups()
更新:
元組解包是Python中的一項有用功能。 為了理解它,我們首先要問什么是元組 。 元組從本質上講是一個不可變的序列-與列表不同,您不能追加或彈出或任何此類填充。 語法上,聲明元組非常簡單-只是幾個用逗號分隔的值。
my_tuple = "I", "am", "awesome"
my_tuple[0] # "I"
my_tuple[1] # "am"
my_tuple[2] # "awesome"
人們通常認為元組實際上是由括號括my_tuple = ("I", "am", "awesome")
–但這是錯誤的; 括號僅在它們闡明或強制執行一定順序的操作時才有用。
元組解包是Python中最可愛的功能之一。 您定義了一個在左側包含未定義名稱的元組數據結構,並將右側的iterable
解壓縮到其中。 右側可以包含任何類型的iterable
,但是其所包含數據的形狀必須與左側名稱的元組結構完全匹配。
# some_var and other_var are both undefined
print some_var # NameError: some_var is undefined
print other_var # NameError: other_var is undefined
my_iterable = ["so", "cool"]
# note that 'some_var, other_var' looks a whole lot like a tuple
some_var, other_var = my_iterable
print some_var # "so"
print other_var # "cool"
再一次,我們不需要右邊的列表,而是任何可迭代的列表,例如生成器:
def some_generator():
yield 1
yield 2
yield 3
a, b, c = some_generator()
print a # 1
print b # 2
print c # 3
您甚至可以使用嵌套數據結構進行元組拆包。
nested_list = [1, [2, 3], 4]
# note that parentheses are necessary here to delimit tuples
a, (b, c), d = nested_list
如果右側的可迭代項與左側的模式不匹配,那么事情就會爆發:
# THESE EXAMPLES DON'T WORK
a, b = [1, 2, 3] # ValueError: too many values to unpack
a, b = [] # ValueError: need more than 0 values to unpack
實際上,這種嘈雜的失敗使元組拆開了我最喜歡的從iterable
項中獲取項目的方式,當我認為iterable
項中僅包含一項時,如果代碼中有多個項目,我希望我的代碼失敗。
# note that the left side below is how you define a tuple of one
bank_statement, = bank_statements # we def want to blow up if too many statements
人們認為多重分配實際上只是簡單的元組拆包。
a, b = 1, 2
print a # 1
print b # 2
這沒什么特別的。 解釋器將等式的右邊視為一個tuple
-請記住,一個元組只是用逗號分隔的值(文字,變量,所評估的函數調用等),然后解釋器將其與左側匹配,就像上面所有示例一樣。
我寫這封信是為了解釋您為該問題獲得的兩個不同答案:
var1, var2 = mySearch.group(1), mySearch.group(2)
和
var1, var2 = mySearch.groups()
首先,要認識到這兩個語句,您的具體情況-在mySearch
是MatchObject
從正則表達式產生有兩個匹配的組-完全是功能上等同。
在元組拆包的性質方面,它們僅相差很小。 第一個在右邊聲明一個元組,第二個使用MatchObject.groups
返回的元組。
這並不是真的適用於您的情況,但是了解MatchObject.group
和MatchObject.groups
行為略有不同可能會很有用(請參見此處和此處 )。 MatchObject.groups
返回正則表達式遇到的所有“子組”(即捕獲組),而MatchObject.group
返回單個組並將整個模式作為可訪問的組進行計數。
實際上,對於這種情況,您應該使用您認為最能表達或最清晰的這兩種方式中的任何一種。 我個人認為在右側提到組1和2是多余的,而MatchObject.groups(0)
返回整個模式匹配的字符串,從而使所有“子組”都偏移為一個索引,這一事實使我一直感到惱火。
在Python中,您可以在一行中用逗號作為定界符來完成多個變量分配。
var1, var2 = mySearch.group(1), mySearch.group(2)
其他答案說關於元組拆包。 因此,如果要將所有捕獲的組內容提取到變量中,那就更好了。 如果要獲取特定的組內容,則必須使用我提到的方法。
va1, var2, var3 = mySearch.group(2), mySearch.group(3), mySearch.group(1)
例:
>>> import re
>>> x = "foobarbuzzlorium"
>>> m = re.search(r'(foo)(bar.*)(lorium)', x)
>>> if m:
x, y = m.group(1), m.group(3)
print(x,y)
foo lorium
您可以一次提取所有組並將它們分配給變量:
var1, var2 = mySeach.groups()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.