使用正则表达式和Python选择具有特殊字符的元素
从字符串列表('16','160','1,2','100,11','1','16:','16:00')中,我只想保留使用正则表达式和Python选择具有特殊字符的元素,python,regex,Python,Regex,从字符串列表('16','160','1,2','100,11','1','16:','16:00')中,我只想保留 两位数字之间有逗号(例如1,2或100,11) 或者有两个数字(不带逗号),后面不跟“:”(即后面不跟任何东西:例如16,或者后面跟任何东西,但不跟“:”:例如160) 我在Python中使用regex尝试了以下代码: import re string = ['16','160','1,2','100,11','1','16:','16:00'] pattern_rate = r
import re
string = ['16','160','1,2','100,11','1','16:','16:00']
pattern_rate = re.compile(r'(?:[\d],[\d]|[\d][\d][^:]*)')
rate = list(filter(pattern_rate.search,string))
print(rate)
打印:
['16','160','1,2','100,11','16:','16:00']
为了正确起见,脚本应该保留前三项并拒绝其余项,但我的脚本拒绝最后两项失败。我猜我使用了错误的“[^:]”符号。我建议深入了解一下正则表达式指南 100不是一个数字,将与
\d
不匹配。如果您不打算否定或以其他方式转换组,则也不需要将组[…]
包含一个元素
第一个查询可以用(?:\d+,\d+
表示。它是一个非捕获组,检测长度大于等于1的逗号分隔数字
第二个查询将在任意(*)数量的not冒号后显示任何匹配三个连续数字的内容
您需要使用类似于(?:\d{2,}(?!:)
的东西。这是一个非捕获组,匹配长度大于等于2的数字,后面不跟冒号<代码>代码>指定负前瞻
在python代码中,您需要使用pattern\u rate.match
而不是pattern\u rate.find
,因为后者将返回部分匹配,而前者仅返回完全匹配
pattern_rate = re.compile(r'(?:\d+,\d+)|(?:\d{2,}(?!:))')
rate = list(filter(pattern_rate.match, string))
我建议您更深入地阅读regex指南 100不是一个数字,将与
\d
不匹配。如果您不打算否定或以其他方式转换组,则也不需要将组[…]
包含一个元素
第一个查询可以用(?:\d+,\d+
表示。它是一个非捕获组,检测长度大于等于1的逗号分隔数字
第二个查询将在任意(*)数量的not冒号后显示任何匹配三个连续数字的内容
您需要使用类似于(?:\d{2,}(?!:)
的东西。这是一个非捕获组,匹配长度大于等于2的数字,后面不跟冒号<代码>代码>指定负前瞻
在python代码中,您需要使用pattern\u rate.match
而不是pattern\u rate.find
,因为后者将返回部分匹配,而前者仅返回完全匹配
pattern_rate = re.compile(r'(?:\d+,\d+)|(?:\d{2,}(?!:))')
rate = list(filter(pattern_rate.match, string))
不确定您是否需要正则表达式:
string = ['16','160','1,2','100,11','1','16:','16:00']
keep = []
for elem in string:
if ("," in elem and len(elem) == 3) or ( ":" not in elem and "," not in elem and len(elem) >= 2):
keep.append(elem)
print (keep)
输出:
['16', '160', '1,2']
虽然没有那么优雅,但往往比使用正则表达式更快。不确定您是否需要正则表达式:
string = ['16','160','1,2','100,11','1','16:','16:00']
keep = []
for elem in string:
if ("," in elem and len(elem) == 3) or ( ":" not in elem and "," not in elem and len(elem) >= 2):
keep.append(elem)
print (keep)
输出:
['16', '160', '1,2']
虽然没有那么优雅,但它往往比使用正则表达式更快
为了正确起见,脚本应该保留前三项并拒绝
其余的,
您可以匹配两个或多个数字,也可以在两个数字之间使用逗号进行匹配
由于列表仅包含数字,因此可以使用在字符串开头开始匹配,而不是在字符串开头开始匹配
解释
非捕获组(?:
匹配2个或更多数字\d{2,}
或|
将两个数字之间用逗号匹配\d\d
关闭非捕获组)
字符串结尾\Z
['16', '160', '1,2']
为了正确起见,脚本应该保留前三项并拒绝
其余的,
您可以匹配两个或多个数字,也可以在两个数字之间使用逗号进行匹配
由于列表仅包含数字,因此可以使用在字符串开头开始匹配,而不是在字符串开头开始匹配
解释
非捕获组(?:
匹配2个或更多数字\d{2,}
或|
将两个数字之间用逗号匹配\d\d
关闭非捕获组)
字符串结尾\Z
['16', '160', '1,2']
谢谢你的回复。我不太明白您为什么在我的问题中提到“100不是一个数字,也不匹配\d”。关于第二个查询,我写了两个连续的'\d',因此它应该显示任何匹配两个连续数字的内容,没有?
[\d],\d]
将不匹配100,10。只有一位数字。相反,第二部分将匹配任何以2位开始但不后跟冒号的数字,例如响应的10,40120kappathanks。我不太明白您为什么在我的问题中提到“100不是一个数字,也不匹配\d”。关于第二个查询,我写了两个连续的'\d',因此它应该显示任何匹配两个连续数字的内容,没有?[\d],\d]
将不匹配100,10。只有一位数字。相反,第二部分将匹配任何以2位开始但不后跟冒号的数字,例如10,40120。顺便问一下,我真的需要非捕获组吗?我复制/粘贴了另一个示例中的内容,但它似乎没有改变任何东西,对吗?@AnthonyHauser如果需要分组,可以使用()
将其设置为捕获组,但不需要捕获组值。这场比赛本身就足够了。如果不使用分组,则可以获得部分匹配。请参见,我需要“()”以便在末尾添加适用于这两个条件的“\Z”?“否则我就不明白你的例子了。”安托尼豪瑟说得对。如果不使用分组,则模式匹配^\d{2,}
或\d\d\Z
(因为它使用了在字符串开头已经匹配的re.match,您可以省略^
),但为什么要添加“^”?不应搜索任何字符