提取特定单词后的所有数字(整数和浮点数)
Posted
技术标签:
【中文标题】提取特定单词后的所有数字(整数和浮点数)【英文标题】:Extract all numbers (int and floats) after specific word 【发布时间】:2021-12-19 04:38:03 【问题描述】:假设我有以下字符串:
str = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222
"""
我想导出所有数字,无论是 int 还是 float 在单词“stop”之后,不区分大小写。所以预期的结果是:
[5.02, 16.1, 5, 2.3222]
到目前为止,我最远的是使用其他帖子中的 PyPi 正则表达式:
regex.compile(r'(?<=stop.*)\d+(?:\.\d+)?', regex.I)
但这个表达式只给了我 [5.02, 16.1]
【问题讨论】:
到目前为止你尝试过什么?您有具体的问题吗? 是的,问题已更新 【参考方案1】:你可以使用:
inp = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222"""
nums = []
if re.search(r'\bstop\b', inp, flags=re.I):
inp = re.sub(r'^.*?\bstop\b', '', inp, flags=re.S|re.I)
nums = re.findall(r'\d+(?:\.\d+)?', inp)
print(nums) # ['5.02', '16.1', '5', '2.3222']
上面的if
逻辑确保我们仅在确定Stop
出现在输入文本中时才尝试填充数字数组。否则,默认输出只是一个空数组。如果Stop
确实出现了,那么我们在使用re.findall
查找之后出现的所有数字之前去掉字符串的前导部分。
【讨论】:
【参考方案2】:import re
_string = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222
"""
start = _string.find("Stop") + len("Stop")
print(re.findall("[-+]?\d*\.?\d+", _string[start:])) # ['5.02', '16.1', '5', '2.3222']
【讨论】:
【参考方案3】:您只会得到前 2 个数字,因为 .*
不匹配换行符。
您可以将更新标志添加到regex.I | regex.S
以使点匹配换行符。
import regex
text = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222
"""
pattern = regex.compile(r'(?<=\bstop\b.*)\d+(?:\.\d+)?', regex.I | regex.S)
print(regex.findall(pattern, text))
输出
['5.02', '16.1', '5', '2.3222']
查看Python demo
如果你想打印在“stop”这个词之后的数字,你也可以使用pythonre
匹配stop,然后将后面的全部捕获到一个组中。
然后你可以取第 1 组的值,并找出所有的数字。
import re
text = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222
"""
pattern = r"\bStop\b(.+)"
m = re.search(pattern, text, re.S|re.I)
if m:
print(re.findall(r"\d+(?:\.\d+)*", m.group(1)))
输出
['5.02', '16.1', '5', '2.3222']
【讨论】:
哈!我现在删除的答案可能看起来很熟悉。 @CarySwoveland 你也可以使用内联修饰符:-)\G
可能更适合 (+1),可变的后视很昂贵。【参考方案4】:
还有一个,虽然是更新的regex
模块:
(?:\G(?!\A)|Stop)\D+\K\d+(?:\.\d+)?
见a demo on regex101.com。
在Python
,这可能是
import regex as re
string = """
HELLO 1 Stop #$**& 5.02‼️ 16.1
regex
5 ,#2.3222
"""
pattern = re.compile(r'(?:\G(?!\A)|Stop)\D+\K\d+(?:\.\d+)?')
numbers = pattern.findall(string)
print(numbers)
并且会产生
['5.02', '16.1', '5', '2.3222']
不要以内置函数命名变量,例如 str
、list
、dict
等。
如果您需要更进一步并将搜索限制在某些范围内(例如,Stop
和 end
之间的所有数字),您也可以使用
(?:\G(?!\A)|Stop)(?:(?!end)\D)+\K\d+(?:\.\d+)?
# ^^^ ^^^
查看另一个demo on regex101.com。
【讨论】:
不错,Jan.^.*\bStop\b(\D*\K\d+(?:\.\d+)?)|\G(?1)
似乎也适用于 PCRE2 (Demo),其中 (?1)
是一个重用捕获组 1 中代码的子例程,但我不能让它工作here,但是...
...您的正则表达式工作正常there。您发现我的变体有问题吗?
@CarySwoveland:它真的不起作用,请参阅here(您有两个很多匹配项,请参阅"1"
)。您可以让它与匹配的对象一起工作。无法访问在递归内部匹配的捕获组,请参阅documentation。这有帮助吗?
是的,很有帮助,但我仍然不明白为什么它适用于 PCRE2 但不适用于 Tio。
@CarySwoveland 这里是the correct demo of your solution。您可能想在此处使用rgx = r'(?ms)^.*?\bStop\b(\D*\K\d+(?:\.\d+)?)|\G(?1)'
,可能与[x.group() for x in re.finditer(rgx, s)]
一起使用。以上是关于提取特定单词后的所有数字(整数和浮点数)的主要内容,如果未能解决你的问题,请参考以下文章