需要正则表达式来匹配格式为 `{word}{.,#}{word}` 的所有模式并严格匹配

Need Regex that matches all patterns with format as `{word}{.,#}{word}` with strict matching

所以我一直在尝试构建一个可以检测模式 {word}{.,#}{word} 并将其分隔为 [word,',' (or '.','#'), word] 的正则表达式。

但我无法创建一个严格匹配此模式并忽略其他所有内容的模式。

我使用了以下正则表达式

r"[\w]+|[.]"

这个做的不错,但是没有严格匹配,如果文本中没有出现 (,, # or .) 字符,它仍然会给出我的话,我不想要。

我想要一个严格匹配上述模式并给我拆分(使用 re.findall)的正则表达式,如果不是 returns 整个单词。

请注意:{,.#}两边的单词,严格来说,两个单词不一定都出现,但至少应该出现一个

一些示例文本供参考:

no.16         would give me ['no','.','16']
#400          would give me ['#,'400']
word1.word2   would give me ['word1','.','word2']

期待所有正则表达式大师的帮助和协助

编辑:

我忘了添加这个。 @viktor 的版本按需工作,只有一个问题,它忽略了 re.findall

期间的所有其他单词

例如。 ONE TWO THREE #400 使用 viktor 的正则表达式给我 ['','#','400']

但预期是 ['ONE','TWO','THREE','#',400]

这可以通过 NLTK 或 spacy 来完成,但使用它们是有限制的。

你可以这样做:

import re

str = "no.16"

pattern = re.compile(r"(\w+)([.|#])(\w+)")

result = list(filter(None, pattern.split(str)))

需要 list(filter(...)) 部分来删除拆分 returns 的空字符串(参见 Python - re.split: extra empty strings that the beginning and end list)。

但是,只有当您的字符串仅包含由您指定的分隔符之一分隔的这两个词时,这才有效。如果模式之前或之后有额外的内容,这也会被split返回。

我建议使用

(\w+)?([.,#])((?(1)\w*|\w+))

参见regex demo

详情

  • (\w+)? - 可选组#1:一个或多个单词字符
  • ([.,#]) - 第 2 组:.,#
  • ((?(1)\w*|\w+)) - 第 3 组:如果第 1 组匹配,则匹配零个或多个单词字符(该单词在右侧是可选的),否则,匹配一个或多个单词字符(必须有标点字符右侧的一个词,因为它们之前没有词)。

Python demo:

import re
pattern = re.compile(r'(\w+)?([.,#])((?(1)\w*|\w+))')
strings = ['no.16', '#400', 'word1.word2', 'word', '123']
for s in strings:
    print(s, ' -> ', pattern.findall(s))

输出:

no.16  ->  [('no', '.', '16')]
#400  ->  [('', '#', '400')]
word1.word2  ->  [('word1', '.', 'word2')]
word  ->  []
123  ->  []

您编辑的答案是

if re.search(r'\w[.,#]|[.,#]\w', text): 
    print( re.findall(r'[.,#]|[^\s.,#]+', text) )

如果在输入字符串中有一个单词 char,然后是三个标点符号中的任何一个,然后又是一个单词 char,您可以找到并提取所有出现的 [.,#]|[^\s.,#]+ 模式,即 .,#,或者除空格 .,# 之外的任何一个或多个字符出现一次或多次。

如果您想用任何提到的特殊字符拆分字符串,我希望这段代码能解决您的问题:

a='no.16'
b='#400'
c='word1.word2'

lst=[a, b, c]

for elem in lst:
    result= re.split('(\.|#|,)',elem)
    while('' in result):
        result.remove('')
    print(result)