python - 通过检查 int 范围替换文本

标签 python xml string text beautifulsoup

我有一条类似 xml 的行,用于记录某些文本的年份范围,例如默认是为所有年份范围值设置 no 属性,如下所示:

textf = """<textf no="1958-1960" no="1961-1963" no="1964-1966" no="1967-1969" no="1970-1972" no="1973-1975" no="1976-1978" no="1979-1981" no="1982-1984" no="1985-1987" no="1988-1990" no="1991-1993" no="1994-1996" no="1997-1999" no="2000-2002" no="2003-2005" no="2006-2008" no="2009-2011" no="2012-2014">Some text</textf>"""

我知道属性应该是年份,值应该是 bool 值 true/false 但这个标准是由其他人设定的,我想使用它。

假设 Some text 来自 1963,我想将 no 更改为 yes 其值为 "1961-1963",即上述文本将变为:

"""<textf no="1958-1960" yes="1961-1963" no="1964-1966" no="1967-1969" no="1970-1972" no="1973-1975" no="1976-1978" no="1979-1981" no="1982-1984" no="1985-1987" no="1988-1990" no="1991-1993" no="1994-1996" no="1997-1999" no="2000-2002" no="2003-2005" no="2006-2008" no="2009-2011" no="2012-2014">Some text</textf>"""

我一直在通过替换整数范围并逐一检查所有年份范围来做到这一点:

from BeautifulSoup import BeautifulSoup
textf = """<textf no="1958-1960" no="1961-1963" no="1964-1966" no="1967-1969" no="1970-1972" no="1973-1975" no="1976-1978" no="1979-1981" no="1982-1984" no="1985-1987" no="1988-1990" no="1991-1993" no="1994-1996" no="1997-1999" no="2000-2002" no="2003-2005" no="2006-2008" no="2009-2011" no="2012-2014">"""
textf_range =  [map(int, j.split('-')) for i,j in BeautifulSoup(textf).find('textf').attrs]
year = 1961
year_range_yes = ['yes="'+str(i)+'-'+str(j)+'"' for i,j in textf_range if year in range(i,j)][0]
year_range_no = year_range_yes.replace('yes=', 'no=')
tagged_textf = textf.replace(year_range_no, year_range_yes)
print tagged_textf

[输出]:

"""<textf no="1958-1960" yes="1961-1963" no="1964-1966" no="1967-1969" no="1970-1972" no="1973-1975" no="1976-1978" no="1979-1981" no="1982-1984" no="1985-1987" no="1988-1990" no="1991-1993" no="1994-1996" no="1997-1999" no="2000-2002" no="2003-2005" no="2006-2008" no="2009-2011" no="2012-2014">Some text</textf>"""

有更简单的方法吗?可能是一种更 pythonic 的方式,不那么复杂,不那么冗长。希望不使用 BeautifulSoup 的方式会受到赞赏。

最佳答案

使用正则表达式:

>>> import re
>>>
>>> def yes_if_include(m, y):
...     y1, y2 = map(int, m.group(1, 2))
...     if y1 <= y <= y2:
...         return 'yes' + m.group()[2:]
...     return m.group()
...
>>> textf = '<textf no="1958-1960" no="1961-1963" no="1964-1966">Some text</textf>'
>>> re.sub(r'no="(\d+)-(\d+)"', lambda m: yes_if_include(m, 1963), textf)
'<textf no="1958-1960" yes="1961-1963" no="1964-1966">Some text</textf>'

关于python - 通过检查 int 范围替换文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27468968/

相关文章:

python - 有效地更改列表列表中的值

python - PyPDF2 尝试提取第一页时返回空白页

java - 在Java中插入和搜索大量数据

string - ZipFile 中的 namelist() 返回编码无效的字符串

python - 如何在Python 3 cgi中将一个页面重定向到另一个页面

python - 使用生成的短语检查输入的 If 语句

java - 如何使用 org.w3c.dom 在属性之间添加新行。 JAVA 中的 XML

javascript - AJAX XML回复节点值迭代

c - C 字符串转换中的段错误

javascript - 正则表达式从字符串中拆分数字