Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在BS4“find_all”中使用正则表达式返回具有模式优先级的匹配项?_Python_Regex_Beautifulsoup - Fatal编程技术网

Python 如何在BS4“find_all”中使用正则表达式返回具有模式优先级的匹配项?

Python 如何在BS4“find_all”中使用正则表达式返回具有模式优先级的匹配项?,python,regex,beautifulsoup,Python,Regex,Beautifulsoup,我有以下正则表达式: import re re.compile('|'.join([pattern1, pattern2, pattern3])) 我希望它能以以下方式工作: 尽量只匹配模式1;如果匹配-停止;否则-继续。 尽量只匹配模式2;如果匹配-停止;否则-继续。 尽量只匹配模式3;停止 但是,目前它与所有这些匹配 我发现了这个,我认为它回答了我的问题,但是添加flags=re。我没有解决我的问题,因为我的结果没有改变 这怎么可能呢 一个可重复的例子: from bs4 import

我有以下正则表达式:

import re

re.compile('|'.join([pattern1, pattern2, pattern3]))
我希望它能以以下方式工作:

尽量只匹配模式1;如果匹配-停止;否则-继续。 尽量只匹配模式2;如果匹配-停止;否则-继续。 尽量只匹配模式3;停止 但是,目前它与所有这些匹配

我发现了这个,我认为它回答了我的问题,但是添加flags=re。我没有解决我的问题,因为我的结果没有改变

这怎么可能呢

一个可重复的例子:

from bs4 import BeautifulSoup

xml_doc = """
    <m3_commodity_group commodity3="Oilseeds"><m3_year_group_Collection><m3_year_group market_year3="2011/12"><m3_month_group_Collection><m3_month_group forecast_month3=""><m3_attribute_group_Collection><m3_attribute_group attribute3="Output"><Textbox40><Cell cell_value3="353.93"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Total
    Supply"><Textbox40><Cell cell_value3="429.49"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Trade"><Textbox40><Cell cell_value3="73.59"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Total
    Use  2/"><Textbox40><Cell cell_value3="345.49"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Ending
    Stocks"><Textbox40><Cell cell_value3="59.03"/></Textbox40></m3_attribute_group></m3_attribute_group_Collection><m3_value_group_Collection><m3_value_group><m3_attribute_group_Collection><m3_attribute_group attribute3="Output"><Textbox40><Cell Textbox44="filler"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Total
    Supply"><Textbox40><Cell Textbox44="filler"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Trade"><Textbox40><Cell Textbox44="filler"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Total
    Use  2/"><Textbox40><Cell Textbox44="filler"/></Textbox40></m3_attribute_group><m3_attribute_group attribute3="Ending
    Stocks"><Textbox40><Cell Textbox44="filler"/></Textbox40></m3_attribute_group></m3_attribute_group_Collection></m3_value_group></m3_value_group_Collection></m3_month_group></m3_month_group_Collection></m3_year_group></m3_year_group_Collection></m3_commodity_group>
    """

soup = BeautifulSoup(xml_doc, "xml")

# This gives 11 vales.
len(soup.find_all(re.compile('|'.join([
    r'^m[0-9]_commodity_group$',r'^m[0-9]_region_group$',r'^m[0-9]_attribute_group$'
]), flags=re.I)))

# This gives 1 value <-- It's what I want, but I want to achieve it with the regex from above (which would work for other texts)
len(soup.find_all(re.compile('|'.join([
    r'^m[0-9]_commodity_group$'
]), flags=re.I)))

# This gives 10 values, which in this example I'd like to be ignored, since the first regex already gave results.
len(soup.find_all(re.compile('|'.join([
    r'^m[0-9]_attribute_group$'
]), flags=re.I)))

您可以重组搜索:

patterns = [r'^m[0-9]_commodity_group$',r'^m[0-9]_region_group$',r'^m[0-9]_attribute_group$']
for pattern in patterns:
    result = soup.find_all(re.compile(pattern, flags=re.I))
    if result:
        break  # Stop after the first time you found a match
else:
    result = None  # When there never was a match

这可能比regex magic更容易理解。如果要经常执行此操作,您可能希望预先编译一次正则表达式,而不是在每次循环迭代时进行预编译。

您可以重新构造搜索:

patterns = [r'^m[0-9]_commodity_group$',r'^m[0-9]_region_group$',r'^m[0-9]_attribute_group$']
for pattern in patterns:
    result = soup.find_all(re.compile(pattern, flags=re.I))
    if result:
        break  # Stop after the first time you found a match
else:
    result = None  # When there never was a match

这可能比regex magic更容易理解。如果要经常执行此操作,您可能希望预编译正则表达式一次,而不是每次循环迭代。

您可以使用for循环遍历列表,如果找到匹配项,则中断

regexList = ['[abc]', '[def]', '[ghi]']
text = input()
for r in regexList:
    mo = re.findall(r, text)
    if mo:
        break
如果只想从正则表达式中查找1个结果,那么可以使用re-python包中的search函数。此包内置于标准python库中

regexList = ['[abc]', '[def]', '[ghi]']
text = input()
for r in regexList:
    mo = re.search(r, text)
    if mo:
        break

不必同时编译所有正则表达式,您可以使用for循环遍历列表,如果找到匹配项,则中断

regexList = ['[abc]', '[def]', '[ghi]']
text = input()
for r in regexList:
    mo = re.findall(r, text)
    if mo:
        break
如果只想从正则表达式中查找1个结果,那么可以使用re-python包中的search函数。此包内置于标准python库中

regexList = ['[abc]', '[def]', '[ghi]']
text = input()
for r in regexList:
    mo = re.search(r, text)
    if mo:
        break

你能举一些例子吗?当然,等一下,我会尝试给出一个可复制的例子example@Thefourthbird-doneCan你能举一些例子吗?当然,等一下,我会尝试给出一个可复制的例子example@Thefourthbird-doneSure,这是我能做的一个有效的选择。我还想知道是否还有一种更优雅/更自然的方式来实现。当然,这是我可以做的一个有效的选择。我还想知道是否还有一种更优雅/本土的方式来实现这一目标。