通过检查int的范围来替换文本

时间:2014-12-14 11:45:38

标签: 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>"""

我知道属性应该是年份,而值应该是布尔值true/false,但是这个标准是由别人设定的,我想要使用它。

我们假设Some text来自 1963 ,我想将no更改为yes,其值为{{1} },即上述文字将成为:

"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>"""

[OUT]:

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

有更简单的方法吗?一种更加诡异的方式,也许更简单,更简洁的方式。希望没有BeautifulSoup的方式会受到赞赏。

1 个答案:

答案 0 :(得分:1)

使用正则表达式:

>>> 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>'