[英]Regular expression to extract number with hyphen
文本類似於“1-2 年。3 年。10 年。”
我想要得到結果[(1,2),(3),(10)]
。
我使用 python。
我首先嘗試r"([0-9]?)[-]?([0-9])years"
。 它工作得很好,除了 10 的情況。我也試過r"([0-9]?)[-]?([0-9]|10)years"
但結果仍然是[(1,2),(3),(1,0)]
。
這應該有效:
import re
st = '1-2years. 3years. 10years.'
result = [tuple(e for e in tup if e)
for tup in re.findall(r'(?:(\d+)-(\d+)|(\d+))years', st)]
# [('1', '2'), ('3',), ('10',)]
正則表達式將在單詞years
之前查找一個或兩個用連字符分隔的數字。 如果我們將其提供給re.findall()
,它將為我們提供 output [('1', '2', ''), ('', '', '3'), ('', '', '10')]
,因此我們還使用快速列表理解來過濾掉空字符串。
或者,我們可以使用r'(\d+)(?:-(\d+))?years'
達到基本相同的效果,這更接近您已經嘗試過的效果。
您的嘗試r"([0-9]?)[-]?([0-9])years"
不適用於10
的情況,因為您要求它匹配每組一個(或零)位數字。
您也不需要括號中的連字符。
這應該有效: Regex101
(\d+)(?:-(\d+))?years
解釋:
(\d+)
:捕獲一個或多個數字的組(?: )
: 非捕獲組-
:連字符(\d+)
:捕獲一個或多個數字的組(?: )?
: 使前面的非捕獲組可選在 python 中:
import re
result = re.findall(r"(\d+)(?:-(\d+))?years", "1-2years. 3years. 10years.")
# Gives: [('1', '2'), ('3', ''), ('10', '')]
列表中的每個元組包含兩個元素:連字符左側的數字和連字符右側的數字。 刪除空白元素非常簡單:循環遍歷result
中的每個item
,然后循環遍歷該項目中的每個match
item
,如果它不為空,則只返回 select(並將其轉換為int
)。
final_result = [tuple(int(match) for match in item if match) for item in result]
# gives: [(1, 2), (3,), (10,)]
您可以使用此模式: (?:(\d+)-)?(\d+)years
請參閱正則表達式演示
代碼:
import re
pattern = r"(?:(\d+)-)?(\d+)years"
text = "1-2years. 3years. 10years."
print([tuple(int(z) for z in x if z) for x in re.findall(pattern, text)])
Output:
[(1, 2), (3,), (10,)]
您只匹配一個數字,因為字符 class [0-9]
不重復。
另一種選擇是將第一位數字與 - 和數字的可選部分匹配。
然后你可以拆分比賽-
\b(\d+(?:-\d+)?)years\.
\b
單詞邊界(
捕獲組 1 (將由 re.findall 返回)
\d+(?:-\d+)?
匹配 1+ 位數字並可選擇匹配-
並再次匹配 1+ 位數字)
關閉組 1years\.
從字面上與轉義匹配.
例子
pattern = r"\b(\d+(?:-\d+)?)years\."
s = "1-2years. 3years. 10years."
res = [tuple(v.split('-')) for v in re.findall(pattern, s)]
print(res)
Output
[('1', '2'), ('3',), ('10',)]
或者如果列表的列表也可以而不是元組
res = [v.split('-') for v in re.findall(pattern, s)]
Output
[['1', '2'], ['3'], ['10']]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.