此原始数据数组的每个元素都由regex
解析['\r\n\t\t\t\t\t\t',
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:',
' 12:00 pm to 03:30 pm & 07:00 pm to 12:00 am\t\t\t\t\t',
'\r\n\t\t\t\t\t\t',
'Sunday:',
' 12:00 pm to 03:30 pm & 07:00 pm to 12:30 am\t\t\t\t\t']
这是我的正则表达式(\\r|\\n|\\t)|(?:\D)(\:)
https://regex101.com/r/fV7wI2/1
请注意,我尝试匹配星期六之后的:
,而不是时间格式中的:
,例如12:00
虽然上面的图像正确地分类捕获/非捕获组
运行re.sub("(\\r|\\n|\\t)|(?:\D)(\:)",'',"Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:")
返回
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturda'
(星期六之后错过'y')
而不是
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday'
为什么会这样?
答案 0 :(得分:2)
如果要检查子字符串是否存在,则需要使用后视而不是非捕获组,但是要将其从匹配项中排除:
import re
s = "Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:"
print(re.sub(r"[\r\n\t]|(?<!\d):",'',s))
# ^^^^^^^
# Result: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
请参阅IDEONE demo
此处,(?<!\d)
仅检查冒号前面的字符是否不是数字。
此外,更改涉及额外开销,最好使用字符类[\r\n\t]
,并且您不需要任何捕获组(圆括号),因为您根本不使用它们。
另外,请注意正则表达式使用原始字符串文字进行初始化,以避免过度使用。
关于非捕获组和否定后卫的一些more details from Python Regular Expression Syntax:
(?<!...)
- 如果字符串中的当前位置前面没有...
的匹配项,则匹配。这被称为负面的后观断言。与正向lookbehind断言类似,包含的模式必须仅匹配某些固定长度的字符串,并且不应包含组引用。以负向lookbehind断言开头的模式可能在被搜索字符串的开头匹配。
(?:...)
- 常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配后或在模式中稍后引用时,无法检索组匹配的子字符串。
后视是零宽度断言(=表达式返回 true 或 false 而不在字符串中进一步移动索引) ,在这种情况下,你想要检查而不是匹配,它们正是你所需要的。非捕获组将消耗部分字符串,因此将成为匹配的一部分。
答案 1 :(得分:1)
\D
为非数字。saturday
y
为non digit
,因此会被删除。
使用
print re.sub("(\\r|\\n|\\t)|(?<=\D):",'',"Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:")
使用lookahead
可确保您在:
/
答案 2 :(得分:1)
我认为您误解了(?:\D)
不会在Regex
中将其作为一个字母考虑,实际上它是错误的,它只是没有将\D
捕获到变量中$1
。每次使用(...)
时,您必须意识到(...)
中的任何模式都会被捕获到变量中$1
,$2
,...中的变量。
解决这个问题的最佳方法是使用正面/负面预测作为@vks和@stribizhev的答案,因为外观只是一个不消耗任何字母的断言,这就是为什么我们称之为&# 34;零宽度断言&#34; 。