检测 python 字符串中的 alphanumeric/numeric 值

Detecting alphanumeric/numeric values in python string

我正在尝试从文本中提取 tokens/part 个具有 numeric/alphanumeric 个字符且长度大于 8 的标记。

示例:

text = ' 510557XXXXXX2302 Normal words 1601371803 NhLw6NlR0EksRWkLddEo7NiEvrg https://www.google.com/search?q=some+google+search&oq=some+google+search&aqs=chrome..69i57j0i22i30l8j0i390.4672j0j7&sourceid=chrome&ie=UTF-8'

预期输出为:

59800512 510557XXXXXX2302 1601371803 NhLw6NlR0EksRWkLddEo7NiEvrg 69i57j0i22i30l8j0i390 4672j0j7

我已经尝试使用正则表达式:((\d+)|([A-Za-z]+\d)[\dA-Za-z]*) 基于答案 Python Alphanumeric Regex。我得到以下结果:

[match for match in re.findall(r"((\d+)|([A-Za-z]+\d)[\dA-Za-z]*)",text)] 

Output :
[('59800512', '59800512', ''),
 ('510557', '510557', ''),
 ('XXXXXX2302', '', 'XXXXXX2'),
 ('1601371803', '1601371803', ''),
 ('NhLw6NlR0EksRWkLddEo7NiEvrg', '', 'NhLw6'),
 ('69', '69', ''),
 ('i57j0i22i30l8j0i390', '', 'i5'),
 ('4672', '4672', ''),
 ('j0j7', '', 'j0'),
 ('8', '8', '')]

我正在为每个匹配的标记获取一个匹配组的元组。

可以再次过滤这些元组。但我正在努力使代码尽可能高效和 pythonic。

有人可以提出解决方案吗?它不需要基于正则表达式。

提前致谢

编辑: 我期望长度等于或大于 8

的字母数字值

您在结果中得到元组,作为 re.findall returns 捕获组的值。

但是您可以省略捕获组并将模式更改为单个匹配,匹配字符 A-Z a-z 之间的至少一个数字,并使用肯定的先行断言至少 8 个字符。

\b(?=[A-Za-z0-9]{8})[A-Za-z]*\d[A-Za-z\d]*\b
  • \b一个单词边界
  • (?=[A-Za-z0-9]{8}) 正面前瞻,断言任何列出的范围至少出现 8 次
  • [A-Za-z]* 可选择匹配字符 A-Z a-z
  • \d匹配一个数字
  • [A-Za-z\d]* 可选匹配字符 A-Z a-z 或数字
  • \b一个单词边界

看到一个regex demo or a Python demo

import re
from pprint import pprint

pattern = r"\b(?=[A-Za-z0-9]{8})[A-Za-z]*\d[A-Za-z\d]*\b"
s = " 510557XXXXXX2302 Normal words 1601371803 NhLw6NlR0EksRWkLddEo7NiEvrg https://www.google.com/search?q=some+google+search&oq=some+google+search&aqs=chrome..69i57j0i22i30l8j0i390.4672j0j7&sourceid=chrome&ie=UTF-8"

pprint(re.findall(pattern, s))

输出

['59800512',
 '510557XXXXXX2302',
 '1601371803',
 'NhLw6NlR0EksRWkLddEo7NiEvrg',
 '69i57j0i22i30l8j0i390',
 '4672j0j7']

我想出了:

\b[A-Za-z]{,7}\d[A-Za-z\d]{7,}\b

在线查看demo

  • \b - 单词边界。
  • [A-Za-z]{,7} - 字母字符的 0-7 倍。
  • \d - 一个数字。
  • [A-Za-z\d]{7,} - 字母数字字符的 7 次以上。
  • \b - 单词边界。

一些示例代码:

import re
s = " 510557XXXXXX2302 Normal words 1601371803 NhLw6NlR0EksRWkLddEo7NiEvrg https://www.google.com/search?q=some+google+search&oq=some+google+search&aqs=chrome..69i57j0i22i30l8j0i390.4672j0j7&sourceid=chrome&ie=UTF-8"
result = re.findall(r'\b[A-Za-z]{,7}\d[A-Za-z\d]{7,}\b', s)
print(result)

打印:

['59800512', '510557XXXXXX2302', '1601371803', 'NhLw6NlR0EksRWkLddEo7NiEvrg', '69i57j0i22i30l8j0i390', '4672j0j7']

您可以选择不区分大小写匹配:

(?i)\b[a-z]{,7}\d[a-z\d]{7,}\b

虽然所选答案 returns 是所需的输出,但它不是通用的,并且无法匹配特定情况(例如,s= "thisword2H2g2d"

对于适用于所有字母数字值组合的更通用的正则表达式:

result = re.findall(r"(\d+[A-Za-z\d]+\d*)|([A-Za-z]+[\d]+[A-Za-z\d]*)")

查看演示 here