【问题标题】:Regex to extract ONLY alphanumeric words正则表达式仅提取字母数字单词
【发布时间】:2023-04-05 15:39:01
【问题描述】:

我正在寻找一个正则表达式来提取仅包含字母数字字符的单词:

string = 'This is a $dollar sign !!'
matches = re.findall(regex, string)
matches = ['This', 'is', 'sign']

这可以通过对字符串进行标记并使用以下正则表达式单独评估每个标记来完成:

^[a-zA-Z0-9]+$

由于性能问题,我希望能够在不标记整个字符串的情况下提取字母数字标记。我最接近的是

regex = \b[a-zA-Z0-9]+\b

,但它仍然会提取包含字母数字字符的子字符串:

string = 'This is a $dollar sign !!'
matches = re.findall(regex, string)
matches = ['This', 'is', 'dollar', 'sign']

是否有正则表达式能够解决这个问题?我尝试了不同的方法,但无法提出解决方案。

【问题讨论】:

  • 提示:您不能为此使用\b,因为$dollar 之间是一个单词边界。

标签: python regex alphanumeric


【解决方案1】:

代替单词边界,向后查找和向前查找空格(或字符串的开头/结尾):

(?:^|(?<= ))[a-zA-Z0-9]+(?= |$)

https://regex101.com/r/TZ7q1c/1

请注意,“a”是一个独立的字母数字单词,因此也包含在内。

['This', 'is', 'a', 'sign']

【讨论】:

  • 为了避免缓慢的逐个字符向前跟踪,我考虑使用所有格匹配,然后在非空格后使用(*SKIP)(*FAIL)ing,但这需要正则表达式模块,它比原生re,尽管采取的步骤更少\s*\K[a-zA-Z0-9]*+(?:\S+(*SKIP)(*FAIL))?,但并没有提供任何速度提升
  • 感谢您的回答。这就是我要找的。在那种情况下,我想在这种情况下使用本机 re 仍然值得吗?另外,您认为这仍然比@hegash 提供的解决方案更快吗?
【解决方案2】:

没有必要为此使用正则表达式,python 有一个内置的isalnum 字符串方法。见下文:

string = 'This is a $dollar sign !!'

matches = [word for word in string.split(' ') if word.isalnum()]

【讨论】:

  • 感谢提醒,我不知道。另一方面,我正在寻找性能最佳的解决方案。我会对其进行测试,但我很确定正则表达式比迭代字符串并根据条件拆分它更快。
【解决方案3】:

[编辑感谢 Khabz 的评论。我误解了这个问题]

根据您的意图,您也可以“拆分”而不是“匹配”。

 >>> matches = re.split(r'(?:\s*\S*[\$\!]+\S*\s*|\s+)', string)

 ['This', 'is', 'a', 'sign', '']

如果您需要删除前导或尾随空字符串:

>>> matches = [x for x in re.split(r'(?:\s*\S*[\$\!]+\S*\s*|\s+)', a) if x ]
['This', 'is', 'a', 'sign']

CertainPerformance 使用后视和前视的响应是最紧凑的。当指定排除时,使用 split 有时是有利的,即上面的正则表达式描述了需要排除的内容。但是,在这种情况下,指定的是包含字母数字,因此使用 split() 不是一个好主意。

【讨论】:

  • 我认为“findall”是等价的。尽管如此,您提供的解决方案与要求不符。 “dollar”不应匹配,因为该单词包含非字母数字字符(“$dollar”)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多