【发布时间】:2022-01-19 22:04:58
【问题描述】:
我正在处理包含字母、数字和特殊字符的字符串。
我正在尝试创建一个 Python 函数来检测 3 个“连续模式”并根据它们的存在返回 true 或 false。模式的一个示例是以下“1/y2”。
这里的四个示例字符串是(y1 和 b1 以及后跟特殊字符 '*' 的模式将被输入,见下文)
- string1 = '1/y1;1/y2;1/y3;1/y4;1/y6;2/b4;5/b5' -> 真(因为 1/y2、1/y3、1/y4是连续的)
- string2 = '1/y2;1/y3;1/y4*;2/y6;2/b4;8/b5' -> False(没有连续模式,因为第三个元素有特殊字符'*'并且需要被排除)
- string3 = '1/y2;1/y3;9/y4' -> False(不是连续模式,因为最后一个元素以 9 开头。)
- string4 = '1/y2;1/y3;1/y4*' -> False(不是连续模式,因为最后一个元素后跟 '*')
- string5 = '1/y2;1/y3;9/y4,2/y2;2/y3;2/y4' -> True(连续模式为 2/y2;2/y3;2/y4)
- string6 = '1/y1;1/y2;1/y3;2/b1;2/b2;2/b3' -> False(虽然有 3 个以 1 开头的连续模式和 3 个以 2 开头的连续模式, 包含 'y1' 和 'b1' 的模式需要被忽略)。
- string7 = = '1/y1;1/y2;1/y3;2/b1;2/b2;2/b3;2/b4' -> True (3个连续模式是2/b2;2/b3 ;2/b4)
这是我的处理过程:
- 以“b”或“y”开头后跟数字(即 b2、b4、y11、y6)的 MATCH 模式
- 如果前一个模式后面有一个“”,则从匹配中排除(即 b2)
- 当 'b' 或 'y' 后跟 1(即 b1, y1)时,从前一个模式的匹配中排除
- 构建一个从正则表达式获取结果并查找连续模式的函数。
现在我只有一个部分工作的代码。我可以使用 itertools 和 itemgetter 从正则表达式结果中找到连续的数字。
def three_consecutive_by_pattern(text):
pattern=r'\w(\d+)(?:;|$)'
# extract b or y pattern the ones followed by *
by_list = re.findall(pattern, text)
# convert result from regex to 'numbers'
by_list = [int(x) for x in by_list]
# find sequence of two or more consecutive numbers
consecutive_list = []
for k, g in itertools.groupby(enumerate(by_list), lambda x: x[1]-x[0]):
final_list = list(map(itemgetter(1), g))
consecutive_list.append(final_list)
# from list remove matches for y1 and b1
list_more_than_3_by = [[ion for ion in sub if ion != 1] for sub in consecutive_list]
list_more_than_3_consecutive_by = []
# find sequence of more than 3 numbers. If present return true
for item in list_more_than_3_by:
if len(item) >= 3:
list_more_than_3_consecutive_by.append(item)
if list_more_than_3_consecutive_by:
return True
else:
return False
这在字符串 1 和字符串 2 上正确执行,但在字符串 3 和字符串 4 上失败。
我正在考虑将正则表达式更改为:
r'([1-9]\/\w\d+)(?:;|$)'
但是当我“将结果从正则表达式更改为数字”时我需要进行更改,并且我相信创建多个列表,具体取决于模式的开始方式?
想法?
谢谢!
【问题讨论】:
-
假设数字可以是任何数量级(例如,
'1y1000;1y1001;1y1002'满足要求),使用正则表达式将无济于事,因为尽管有些人很聪明,但它们无法执行算术运算。 -
不清楚,但是如果您只需要检查前三个元素中的第一个数字并验证模式,请尝试like this demo。 @CarySwoveland 解释说,仅通过正则表达式无法检查递增的数字(您需要一个回调函数)。
-
正则表达式无法计数。你问的是这个吗?
-
不,正则表达式只是起点。其余的功能是我需要调整的。只有当模式共享相同的前三个字符时,它现在才能正常工作,即。 1/y2;1/y3;1/y4,这些我认为是连续的,所以函数应该返回 true。但如果第一个或第三个字符不同,例如 1/y2;1/y3;9/y4,则不起作用,因为第三个模式中的 9,这些不是连续的,应该返回 false。
标签: python regex text-parsing