正则表达式无法排除带换行符的匹配项

2024-10-03 00:27:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我运行以下正则表达式。为了更清晰,我使用变量对其进行了分解:

all_no_numb_newline = r'(?:[^\n\d]*\n)' ## I include an extra line just to get more context ##
all_no_numb = r'(?:[^\n\d]*)' ## I do not want there to be any numbers on the same line except the ID ##
x1 = r'(?!(1-888-555|\(888\)))' ## I am excluding a specific common phone number ##
x2 = r'(?![\n\/])\W{0,2}' ## I am excluding line breaks and date formats ##
id_re = f'({x1}\d(?:{x2}\d){{16}}\d)' ## This is an ID number 18 digits long with some symbols in between ##

基本上,我试图识别一个18位长的ID我不想匹配包含任何字母、换行符或正斜杠的18位数字。如果我将一个18位的ID与其他随机符号相匹配,那就可以了。我也不想与前面有任何数字的ID相匹配。我还想在主组前面多配一行,以便更好地了解我的比赛情况,但是我确实在id重新匹配之后(这就是为什么我在所有的“不”新行旁边加了一个问号“?”

然后,我使用以下命令运行以下代码:

re.findall(
    "("+
    all_no_numb_newline+"?"+
    all_no_numb+
    id_re+")"
    , text)[0]

但是,这仍然返回以下匹配:

('L1 (061510)\n1009671-1000', '1 (061510)\n1009671-1000', '')

我预计不会有换行,我预计会有两个组(我的普通比赛组和我的ID组)。为什么有3组而不是2组?为什么比赛中会出现“\n”(换行)

编辑:匹配示例

'Mortgage\nID 756953480812037780'
')\n*DT756953480812037780'
'\nq75695348081 0233 240'
')\n*DT756953480812037780'
'\nq03313375233 0233 329'
'ID 676170114397739293'
'ID NUMBER 676170114397739293'
'ID\n676170114397739293'
'ID676170114397739293'

OUTPUT:

'756953480812037780'
'756953480812037780'
'75695348081 0233 240'
'756953480812037780'
'03313375233 0233 329'
'676170114397739293'
'676170114397739293'
'676170114397739293'
'676170114397739293'

编辑:不应匹配的示例

'L1 (061510)\n1009671-1000'
'L1 081510)\n1009671-1000'
'L1 (061510)\n1009671-1000'

Tags: thetonoreanidl1line
2条回答

我不认为Ryszard的回答排除了\n。我用了一种更骇人的方式:

                YY = r'(?!-888-)'
                XX = r'[^A-Za-z\d\n\\\/\)\(]{0,2}'
                id_re= f'({YY}\d(?:{XX}\d|\d{XX}){{16}}\d)'

YY取消了显示普通电话号码的功能 XX保留所有非字母数字字符,不包括\n。无论我执行了多少lookahead/behind,其他过程都会显示\n。因此,我决定使用一种更简单但更简单的手工路线,消除所有字母数字和\n(以及将日期或电话号码与斜线和括号混淆的额外符号)

这个正则表达式非常成功,我几乎得到了99%的匹配

使用

(?<!\d)\d(?:\s*\d){16}\d(?!\d)

proof

解释

                                        
  (?<!                     look behind to see if there is not:
                                        
    \d                       digits (0-9)
                                        
  )                        end of look-behind
                                        
  \d                       digits (0-9)
                                        
  (?:                      group, but do not capture (16 times):
                                        
    \s*                      whitespace (\n, \r, \t, \f, and " ") (0
                             or more times (matching the most amount
                             possible))
                                        
    \d                       digits (0-9)
                                        
  ){16}                    end of grouping
                                        
  \d                       digits (0-9)
                                        
  (?!                      look ahead to see if there is not:
                                        
    \d                       digits (0-9)
                                        
  )                        end of look-ahead

相关问题 更多 >