python 用于指定单词内字符的正则表达式模式

rbpvctlc  于 2023-09-29  发布在  Python
关注(0)|答案(4)|浏览(90)

显然我的问题不够具体。我会在我原来的问题下面加上我的答案。

问题:我有三个数字的字符词。例如,001,002,003。如果有像Q04(而不是004)这样的转换错误,我需要一个正则表达式模式来识别这种错误。

要求:

  • 由空格字符分隔的至少包含一个大写字母的三位数字的单词
  • 模式应该 * 不 * 匹配004, 014, 114类型示例
  • 最大值为200

我计划在一堆文本文件中识别这些错误。

其他信息为了清楚起见被省略了(显然我本可以更清楚地说明这一点)

测试字符串(仅滚动条目编号003正确。其他00Q, 0Q2等是不正确的,需要这样标识:

text = '00Q ALLAN, Wilham Ross 0Q2 ALLARDYCE, Margaret Isabel 003 ALLARDYCE, Mervyn George Q04 ANKER. Delia Roswyn QQ5 ANKER, Doreen Alison'

我最终使用下面的Python代码和我自己的正则表达式来识别这些错误。

# matchTestSub.py

import re

def isValidInteger(string):
    try:
        int(string)  # Try to convert the string to an integer
        return True  # If successful, it's a valid integer
    except ValueError:
        return False  # Conversion to integer failed, not a valid integer

text = '00Q ALLAN, Wilham Ross 0Q2 ALLARDYCE, Margaret Isabel 003 ALLARDYCE, Mervyn George Q04 ANKER. Delia Roswyn QQ5 ANKER, Doreen Alison'        

pattern1 = r'\b[A-Z0-9]{3}\b(?![A-Z]+)'
match = re.findall(pattern1,text)
if match:
    for i in range(len(match)):
        x = match[i]
        
        print(x,isValidInteger(x))

我的正则表达式和测试字符串是here
我对正则表达式模式的想法是:

  • 消除其他字符串匹配,如对多个大写字符使用负向前查找的名称(?![A-Z]+)
  • 匹配包含数字和/或大写字母的3字符单词
unftdfkk

unftdfkk1#

一个简单的awk,它将识别您描述的模式:

awk 'BEGIN{RS="[[:space:]\n]+"}
($1!=$1+0)||$1>200||length($1)>3{print $1}' file

给出:

cat file
001 002 003 Q04 250 
006 0Q2 1234 0002

图纸:

Q04
250
0Q2
1234
0002

或者如果您只需要符合条件的号码:

awk 'BEGIN{RS="[[:space:]\n]+"}
($1!=$1+0)||$1>200||length($1)>3{next}1' file

图纸:

001
002
003
006
jqjz2hbq

jqjz2hbq2#

要匹配由空格(或在开始/结束)分隔的 * 三个字母的单词 *,这些单词不包含字母,并且从 * 三位数字 * 200是最大数量:

\b(?<!\S)(?!\D{3}|200|[01]\d\d)[A-Z\d]{3}(?!\S)

See this demo at regex101(不应该匹配任何 *4+字母单词 *,例如1000

  • \bword boundary开头(仅为了提高效率)
  • (?<!\S)向后查找非空白(开始或空白在前)
  • (?!\D{3}|200|[01]\d\d)look ahead表示非三个 * 非数字 *(仅字母)

或者如果是一个数字(仅限数字),不在指定的有效范围0-200内

  • [A-Z\d]{3}匹配三个大写字母和/或数字
  • (?!\S)后面不跟 * 非空格 *(后面跟空格或end)

要进一步匹配四位或更多位数的数字,它可以是easily adjusted (demo)

k4aesqcs

k4aesqcs3#

你可以做的是用一个“积极的前瞻”来Assert“词边界”。
然后,用另一个 * 积极的前瞻 * 来细化Assert,在任何位置匹配字母 Q

\b(?=[\dQ]{3})(?=Q..|.Q.|..Q)...

这里有一个例子。

l = [x.group() for x in re.finditer(r'\b(?=[\dQ]{3})(?=Q..|.Q.|..Q)...', s)]

输出

['00Q', '0Q2', 'Q04', 'QQ5']
qlfbtfca

qlfbtfca4#

与其使用复杂的正则表达式来完成所有的工作,我会使用一种更简单的方法,只需两步一行程序:

解决方案

import re
teststring = '00Q ALLAN, Wilham Ross 0Q2 ALLARDYCE, Margaret Isabel 003 ALLARDYCE, Mervyn George Q04 ANKER. Delia Roswyn QQ5 ANKER, Doreen Alison'
[char3 for char3 in re.findall(r'(?<=\b)[\dA-Z]{3}(?=\b)', teststring) if not re.match('\d{3}', char3)]

结果

['00Q', '0Q2', 'Q04', 'QQ5']

如何运作

第一遍将检查包含大写字母或数字的三个字符,这些字符前后都有单词边界(\b)
第二遍检查是否不是3位数。
第一个的结果通过数组解析被流水线传输到第二个。这种方式应该是快速的整体,没有额外的数组创建。

相关问题