【问题标题】:Detecting alphanumeric/numeric values in python string检测python字符串中的字母数字/数字值
【发布时间】:2021-07-26 13:52:29
【问题描述】:

我正在尝试从文本中提取具有长度大于 8 的数字/字母数字字符的标记/部分标记。

例子:

text = 'https://stackoverflow.com/questions/59800512/ 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 的字母数字值

【问题讨论】:

  • 请注意,当您有“长度大于 8”这样的要求时,您期望得到“4672j0j7”和“59800512”这样的结果似乎很奇怪。
  • @JvdV - 我在陈述问题时犯了错误。我希望长度等于或大于 8 的字母数字值。这正是在文本字符串中添加示例的原因:“4672j0j7”和“59800512”。我已经编辑了问题。

标签: python regex numeric re alphanumeric


【解决方案1】:

您会在结果中获得元组,因为 re.findall 返回捕获组的值。

但您可以省略捕获组并将模式更改为单个匹配,匹配字符 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 demoPython 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 = "https://stackoverflow.com/questions/59800512/ 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']

【讨论】:

  • @第四只鸟 - 非常感谢您的回答和解释。效果很好。
【解决方案2】:

我想出了:

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

在线查看demo

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

一些示例代码:

import re
s = "https://stackoverflow.com/questions/59800512/ 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

【讨论】:

  • @JvdV - 它非常简单并且有效。我将选择这个答案,因为它很简单。非常感谢您的回答和解释。
【解决方案3】:

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

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

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

查看演示 here

【讨论】:

    猜你喜欢
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 2012-02-17
    • 1970-01-01
    相关资源
    最近更新 更多