我是regex的新手,我无法弄清re.sub
中的regex替换。
import re
test_cases = [
"1-Some String #0123",
"2-Some String #1234-56-a",
"3-Some String #1234-56A ",
"4-Some String (Fubar/ #12-345-67A)",
"5-Some String (Fubar - #12-345.67 A)",
"6-Some String / #123",
"7-Some String/#0233",
"8-Some #1 String/#0233"
]
for test in test_cases:
test = re.sub(r'[/|#][A-Z|a-z|0-9|-]*','', test)
print(test)
代码应打印:
1-Some String
2-Some String
3-Some String
4-Some String (Fubar)
5-Some String (Fubar)
6-Some String
7-Some String
8-Some #1 String
但是,相反,我目前正在获取此信息(其中4,5,8未完全转换):
1-Some String
2-Some String
3-Some String
4-Some String (Fubar )
5-Some String (Fubar - .67 A)
6-Some String
7-Some String
8-Some String
答案 0 :(得分:3)
请尝试以下操作:
import re
test_cases = [
"1-Some String #0123",
"2-Some String #1234-56-a",
"3-Some String #1234-56A ",
"4-Some String (Fubar/ #12-345-67A)",
"5-Some String (Fubar - #12-345.67 A)",
"6-Some String / #123",
"7-Some String/#0233",
"8-Some #1 String/#0233"
]
for test in test_cases:
test = re.sub(r'\s*([/#]|- )[\sA-Za-z0-9-#\.]*(?=(\)|$))','', test)
print(test)
结果:
1-Some String
2-Some String
3-Some String
4-Some String (Fubar)
5-Some String (Fubar)
6-Some String
7-Some String
8-Some #1 String
正则表达式(要删除的子字符串)可以定义为:
然后正则表达式将如下所示:
\s*([/#]|- )[\sA-Za-z0-9-#\.]*(?=(\)|$))
positive lookahead
可能需要一些解释。模式(?=regex)
是一个零宽度的断言,表示followed by regex
。
好处是匹配的子字符串不包含regex
和
您可以将其用作anchor
。
答案 1 :(得分:2)
另一种选择是使用负超前(?![^#\n\r]*#)
仅匹配#的最后一次出现。为了清楚起见,我在方括号之间放置了一个空格[ ]
。
[ ]*(?:[/-][ ]*)?#(?![^#\n\r]*#)[\da-zA-Z. -]+
说明
[ ]*
匹配一个空格0次以上(?:[/-][ ]*)?
可以选择匹配/
或-
和0+个空格#
字面上匹配(?![^#\n\r]*#)
负向查找,断言当权利不包含#
[\da-zA-Z. -]+
匹配1次以上字符类中列出的内容在替换中,使用一个空字符串。
答案 2 :(得分:1)
分两个步骤进行操作可能更容易:
首先:清除括号中的零件。在'('和一些字母之后,删除所有内容,直到结尾的')'。
第二个:删除行末的多余内容。一行以'#'结尾,后跟2个或多个数字或'/'。可能在'#'或'/'之前有一个空格。
import re
paren_re = re.compile(r"([(][a-zA-Z]+)([^)]*)")
eol_re = re.compile(r"(.*?)\s*(?:#\d\d|/).*")
for line in test_cases:
result = paren_re.sub(r"\1", line)
result = eol_re.sub(r"\1", result)
print(result)
答案 3 :(得分:0)
我无法将它们放入一个正则表达式中,也许有人可以。这是两行解决方案:
import re
test_cases = [
"1-Some String #0123",
"2-Some String #1234-56-a",
"3-Some String #1234-56A ",
"4-Some String (Fubar/ #12-345-67A)",
"5-Some String (Fubar - #12-345.67 A)",
"6-Some String / #123",
"7-Some String/#0233",
"8-Some #1 String/#0233"
]
for test in test_cases:
test = re.sub(r'[\/#][\w\s\d\-]*', '', test)
test = re.sub(r'[\s\.\-\d]+\w+\)', ')', test)
print(test)
输出:
1-Some String
2-Some String
3-Some String
4-Some String (Fubar)
5-Some String (Fubar)
6-Some String
7-Some String
8-Some
说明:
\w
for a-zA-Z
\d
for 0-9
\s
(空格)\.
表示点\-
减但是我对您的最后一行输出感到困惑,为什么它基于什么输出#1 String
?如果您确认可以为该模式编写特定的正则表达式。