【问题标题】:how to replace a substring in a list of strings in python?如何替换python中字符串列表中的子字符串?
【发布时间】:2021-12-19 14:34:04
【问题描述】:

所以我使用beautifulsoup 来抓取维基百科页面中的表格,在该页面中我提取文件中的数据。 问题是我想删除为表中的列生成的列表中的一些子字符串

这是我的代码:

soup= bs(result.text,'html.parser')

country_names= soup.find('table', class_= 'wikitable sortable').tbody

rows= country_names.find_all('tr')
columns=[v.text.replace('[a][b][13]\n', '') for v in rows[0].find_all('th')]
print(columns)

我所能做的就是使用替换函数从列表中的字符串中只删除一个子字符串。

replace()函数之前的输出:

['Flag\n', 'Map\n', 'English short nameandformal name[6][7][8]\n', 'Local short name(s)andformal name(s)[6][7]\n', 'Capital[8][9][10]\n', 'Population (2018)[11][12]\n', 'Area[a][b][13]\n']

replace()函数后的输出:

['Flag\n', 'Map\n', 'English short nameandformal name[6][7][8]\n', 'Local short name(s)andformal name(s)[6][7]\n', 'Capital[8][9][10]\n', 'Population (2018)[11][12]\n', 'Area']

所以我想删除所有子字符串,例如 '[8][9][10]\n'、' [6][7]\n '、'[6][7][8]\n' 和 '(2018)[11][12]\n' 等等,但我无法找到解决方案,因为我对 python 和 beautifulsoup 还很陌生。

【问题讨论】:

  • 这个问题与美丽的汤或网络爬行没有任何关系:)。我认为您可以删除问题的那部分(和标签)。
  • 问题实际上不是“如何在 python 中替换字符串列表中的子字符串?”,因为您已经展示了可以做到这一点的代码:您有一个字符串列表,并且您成功替换包含它的每个字符串中的子字符串[a][b][13]。 问题是如何替换任何匹配模式的子字符串;显然,一旦你有了那个工具,你就已经知道如何将它应用到列表中了。 (您显然也知道如何使用 BeautifulSoup 和列表推导式。)问您真正需要帮助的问题会很有帮助。
  • 创建关注该问题的示例也很有帮助。请阅读stackoverflow.com/help/minimal-reproducible-example。
  • 但是,一旦你提出了你实际遇到的问题,research 就容易多了(expected 也是如此)。

标签: python beautifulsoup web-crawler


【解决方案1】:

我建议您深入研究正则表达式:

使用例如\[\d+\] 作为括号内任意位数的表达式。

import re
org_string = 'Capital[8][9][10]\n'
pattern = r'\[\d+\]'
mod_string = re.sub(pattern, '', org_string )
# Capital

【讨论】:

    【解决方案2】:

    我认为这是您正在寻找的解决方案:

    import re
    colums = [re.sub('(\[[0-9]+])', '', i).replace('\n', '') for i in rows]
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    • 那么我怎样才能消除 [a] 和 [b] 以及我想要的任何其他子字符串。我可以在sub() 中添加我想消除的附加条件吗?还是只有一种模式?另外,我如何在搜索时正确获得正确的模式或语法,但找不到正确的方法
    【解决方案3】:

    您可以为此使用 python re 正则表达式库。 re 库有一个函数 re.sub(pattern,replace_string,input_string) 将替换任何与模式正则表达式匹配的子字符串。

    类似这样的:

    # make sure to import the re module
    import re
    
    columns = [re.sub('(\[[a-zA-Z\d]*\])+\n','',v.text) for v in rows[0].find_all('th')]
    

    编辑:更改正则表达式模式

    【讨论】:

    • 我试过了,但不能应用于整个列表,总和字符串仍然有模式中应该消除的部分。有没有办法在模式中添加其他条件?
    • 是的,您绝对可以在模式中添加其他内容。你还想替换什么?
    【解决方案4】:

    您想要的输出需要在列表理解中使用正则表达式:

    import re
    
    list_before = ['Flag\n', 'Map\n', 'English short nameandformal name[6][7][8]\n', 'Local short name(s)andformal name(s)[6][7]\n', 'Capital[8][9][10]\n', 'Population (2018)[11][12]\n', 'Area[a][b][13]\n']
    
    pattern = r'(\(\d+\))*(\[\w+\])*\n?'
    
    list_after = [re.sub(pattern, "", elem).strip() for elem in list_before]
    

    pattern 定义了您要在list_before 的每个字符串中替换的正则表达式模式。您可能想更深入地研究正则表达式以完全理解它,但用简单的英语来说,此模式匹配:

    • 0 次或多次出现“(”,后跟 1 位或多位数字(由特殊序列 \d 表示),后跟“)”
    • 0 次或多次出现“[”,后跟 1 或多个字母数字字符(由特殊序列 \w 指示),后跟“]”
    • 0 次或 1 次新行 \n

    最后,列表推导中的 re.sub() 方法将所有匹配项替换为 ""。

    输出是:

    ['Flag', 'Map', 'English short nameandformal name', 'Local short name(s)andformal name(s)', 'Capital', 'Population', 'Area']
    

    【讨论】:

      猜你喜欢
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 2020-08-03
      • 1970-01-01
      • 2019-06-26
      • 2019-11-08
      • 1970-01-01
      相关资源
      最近更新 更多