我想用空格替换所有非字母字符,不包括1950年到2029年之间的年份。 E.g:
ab-c 0123 4r. a2017 2010
- > ab c r a 2010
我到目前为止的尝试,试图通过负面预测将日期列入黑名单:
re.sub('(?!\b19[5-9][0-9]\b|\b20[0-2][0-9]\b)([^A-Za-z]+)', ' ', string)
由于这不起作用,非常感谢任何帮助!
答案 0 :(得分:2)
你可以使用一个简单的正则表达式并传递一个函数来检查它是否是一年:
path.repo: /your/path/to/repo
为了保持正则表达式和逻辑简单,您可以在第二步中删除特殊字符:
import re
def replace_non_year_numbers(m):
number = int(m.group(0))
if 1950 <= number <= 2029:
return str(number)
else:
return ''
print(re.sub('\d+', replace_non_year_numbers, 'ab-c 0123 4r. a2017 2010'))
# 'ab-c r. a2017 2010'
答案 1 :(得分:1)
让我们选择您想要保留在结果中的内容。看看正则表达式:
(
(?<!\w) # neg. lookbehind: not a word char
(1 # read a '1'
(?=9[5-9][0-9]) # lookahead: following 3 digits make it
# a year between 1950 and 1999
[0-9]{3} # THEN read these 3 digits
| # - OR -
2 # read a '2'
(?=0[0-2][0-9]) # lookahead: following 3 digits make it
# a year between 2000 and 2029
[0-9]{3} # THEN read these 3 digits
)
| # - OR -
[a-zA-Z] # read some letter
)+
在oneliner:
((?<!\w)(1(?=9[5-9][0-9])[0-9]{3}|2(?=0[0-2][0-9])[0-9]{3})|[a-zA-Z])+
您可以在regex 101
上进行测试让我们把它放在python脚本中:
$ cat test.py
import re
pattern = r"(?:(?<!\w)(?:1(?=9[5-9][0-9])[0-9]{3}|2(?=0[0-2][0-9])[0-9]{3})|[a-zA-Z])+"
tests = ["ab-c 0123 4r. a2017 2010 a1955 1955 abc"]
for elt in tests:
matches = re.findall(pattern, elt)
print ' '.join(matches)
给出:
$ python test.py
ab c r a 2010 a 1955 abc
答案 2 :(得分:0)
不太漂亮,但我会使用多次替换:
import re
def check_if_year(m):
number = int(m.group(0))
if 1950 <= number <= 2029:
return str(number)
else:
return ' '
s = 'ab-c 0123 4r. a2017 2010 1800' # Added 1800 for testing
print(s)
print('ab c r a 2010')
t = re.sub(r'[^A-Za-z0-9 ]+', ' ', s) # Only non-alphanumeric
t = re.sub(r'(?!\b\d{4}\b)(?<!\d)\d+', ' ', t) # Only numbers that aren't standalone 4 digits
t = re.sub(r'\d+', check_if_year, t) # Only standalone 4 digits number and test for year
t = re.sub(r' {2,}', ' ', t).strip() # Clean up extra spaces
print(t)
(?!\b\d{4}\b)(?<!\d)\d+
只要不是4位数字,就会匹配任何数字。 (除了空格或字符串开头/结尾之外没有任何字符),我使用(?<!\d)
,以便它不会在数字中间尝试匹配。