簡體   English   中英

python重新匹配組

[英]python re match groups

我想從字符串中提取一些字段,但是我不確定它們有多少。 我使用了regexp,但是有一些我不理解的問題。

例如:

  199  -> (199)
  199,200  -> (199,200)
  300,20,500 -> (300,20, 500)

我嘗試了一下,但是在某種程度上我無法使它正常工作。 希望任何人都能給我一些建議。 我會感激的

我嘗試過的正則表達式:

>>> re.match('^(\d+,)*(\d+)$', '20,59,199,300').groups()
('199,', '300')
// in this, I do not really care about ',' since I could use .strip(',') to trim that. 

我做了一些谷歌:並嘗試使用re.findall,但我不確定如何獲得此:

>>> re.findall('^(\d+,)*(\d+)$', '20,59,199,300')
[('199,', '300')]

-------------------------------------------------- ----更新

我意識到,如果不講述整個故事,這個問題可能會令人困惑。 基本上我想驗證crontab中定義的語法(或類似的語法)

我為_VALID_EXPRESSION創建一個數組:這是一個嵌套元組。

 (field_1,
  field_2,
 )

對於每個field_1,它都有兩個元組,

 field_1:   ((0,59),        (r'....', r'....'))
            valid_value   valid_format 

在我的代碼中,它看起來像這樣:

_VALID_EXPRESSION =  \
 12     (((0, 59), (r'^\*$', r'^\*/(\d+)$', r'^(\d+)-(\d+)$',
 13                 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')),   # second
 14      ((0, 59), (r'^\*$', r'^\*\/(\d+)$', r'^(\d+)-(\d+)$',
 15                 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')),   # minute
 16        .... )

在我的解析函數中,我要做的就是提取所有組,然后查看它們是否在有效值之內。

我需要的regexp之一是它能夠正確匹配此字符串'50,200,300',並在這種情況下提取所有數字。 (當然,我可以使用split(),但這會背離我的初衷。因此,我不喜歡這個想法。)

希望這會有所幫助。

為什么不只使用string.split?

numbers = targetstr.split(',')

使用正則表達式的最簡單解決方案是:

r"(\d+,?)"

您可以使用findall來獲得300,20,500是你想要的。 或者,如果您不想使用逗號:

r"(\d+),?"

這與1個或多個數字組成的組匹配,后跟0或1個逗號(不在組中)。

無論哪種方式:

>>> s = '300,20,500'
>>> r = re.compile(r"(\d+),?")
>>> r.findall(s)
['300', '20', '500']

但是,正如Sahil Grover指出的那樣,如果這些是您的輸入字符串,則等效於僅調用s.split(',') 如果您的輸入字符串可能包含非數字,那么這將確保您僅匹配數字字符串,但即使這樣也可能更簡單,例如filter(str.isdigit, s.split(','))

如果要使用inttuple而不是strlist

>>> tuple(map(int, r.findall(s)))
(300, 20, 500)

如果您發現解析/生成器表達式比map / filter調用更易於閱讀:

>>> tuple(int(x) for x in r.findall(s))
(300, 20, 500)

或者,更簡單地說:

>>> tuple(int(x) for x in s.split(',') if x.isdigit())
(300, 20, 500)

而且,如果您想要字符串(300, 20, 500) ,當然可以通過僅在tuple上調用repr來做到這一點,那么有一種更簡單的方法可以做到這一點:

>>> '(' + s + ')'
'(300, 20, 500)'

您原來的正則表達式:

'^(\d+,)*(\d+)$'

…將正好返回兩組,因為模式中恰好有兩組。 而且,由於您將它顯式地包裝在^$ ,因此它必須匹配整個字符串,因此findall不會在這里為您提供幫助-它會找到與match完全相同的(兩個) match

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM