找出一个句子中有多少个单词满足特定条件



有一个招聘任务,我想只用正则表达式来解决。

一个句子是由一组单词组成的。每个单词由字母[a-zA-Z]组成,可以包含一个或多个破折号,并以句号(.)、逗号(,)、问号(?)或感叹号(!)等标点符号结尾。每个单词不能以非字母或数字开头。以空格分隔的单个字母也可以。

破折号将两个或多个单词连接成一个单词,应该被接受(但双破折号"——")而更多的不是),而其他有效的标点符号,在单词的末尾,应该被删除。

有效词(示例):

  • "foo ? !,":结果="foo-foo",
  • "f-foo-foo ? !,":结果="f-foo-foo",

无效字(示例):

  • "! @foo-foo{{}}}(">
  • "foo - foo"
  • "f-foo@ -@foo"
  • "f123-foo123-foo产生绯闻。
  • "-f-foo-foo产生绯闻。

我试图在python中仅使用regex解决问题:

import re
TESTSTR1 = 'there should be 9 valid  words, including: a well-behave, right?'
TESTSTR2 = 'blabla! bla121 {{blabla123bla.. bla-blablabla!! b;a-bla@!. blabla bla-bla-bla-bla **bla-bla'
TESTSTR3 = '{{)foo! ~~foo121 foo--foo?. foo-foo?!{. @foo-foo! f 23 foo2 f-ff-fff-ffff!.,?  **foo-f'
TESTSTR1_EXPECTED = ['there', 'should', 'be', 'valid', 'words', 'including', 'a', 'well-behave','right']
TESTSTR2_EXPECTED = ['blabla', 'bla-blablabla', 'blabla', 'bla-bla-bla-bla', 'bla-bla']
TESTSTR3_EXPECTED = ['f', 'f-ff-fff-ffff','foo-f']

def find_words(sentence: str) -> list:
pattern_dash = r'b([^ds]+(?:-w+[a-zA-Z]*))b'
pattern = r'b(?!w+-w+)(?!-w+)[a-zA-Z]+b'
words = re.findall(pattern_dash, sentence)
words += re.findall(pattern, sentence)
return words

if __name__ == "__main__":
print('====================== TEST1 ======================')
print(f'Expected "TESTSTR1" = {TESTSTR1_EXPECTED}')
print(f'Result "TESTSTR1"   = {find_words(TESTSTR1)}')

print('====================== TEST2 ======================')
print(f'Expected "TESTSTR2" = {TESTSTR2_EXPECTED}')
print(f'Result "TESTSTR2"   = {find_words(TESTSTR2)}')
print('====================== TEST3 ======================')
print(f'Expected "TESTSTR3" = {TESTSTR3_EXPECTED}')
print(f'Result "TESTSTR3"   = {find_words(TESTSTR3)}')

首先我想找到所有包含破折号("pattern_dash")的有效单词,然后是所有其他有效单词(不包括那些已经找到的)。

我尝试了许多不同的正则表达式组合,但没有成功。我不确定该任务是否仅使用正则表达式即可解决。

是否有人知道它是可能的解决它只使用正则表达式?你知道怎么做吗?

多谢

要获得示例数据中的匹配项,可以使用捕获组。

首先匹配空格或*,然后仅用a- za -z捕获单词,可选地用-分隔,并断言单词以空格、字符串的结尾或1个或多个标点符号结束,这些标点符号后跟一个右侧空白边界。

(?:[ *]|^)([a-zA-Z]+(?:-[a-zA-Z]+)*)(?= |$|[.,!?:]+(?!S))

部分模式匹配:

  • (?:[ *]|^)非捕获组,匹配*或断言字符串
  • 的开头
  • (Capturegroup 1
    • [a-zA-Z]+A-Za-z匹配1+次
    • (?:-[a-zA-Z]+)*可选地在-
    • 之前重复相同的内容
  • )关闭组1
  • (?=正向前看,断言直接向右是
    • 匹配空格
    • |
    • $断言字符串的结束
    • |
    • [.,!?:]+(?!S)从字符类[.,!?:]中匹配1个或多个字符,并在右侧断言一个空白边界
  • )Close forward

查看正则表达式演示和Python演示

例如

import re
strings = [
"there should be 9 valid  words, including: a well-behave, right?",
"blabla! bla121 {{blabla123bla.. bla-blablabla!! b;a-bla@!. blabla bla-bla-bla-bla **bla-bla",
"{{)foo! ~~foo121 foo--foo?. foo-foo?!{. @foo-foo! f 23 foo2 f-ff-fff-ffff!.,?  **foo-f"
]
pattern = r"(?:[ *]|^)([a-zA-Z]+(?:-[a-zA-Z]+)*)(?= |$|[.,!?:]+(?!S))"
for s in strings:
print(re.findall(pattern, s, re.M))

输出
['there', 'should', 'be', 'valid', 'words', 'including', 'a', 'well-behave', 'right']
['blabla', 'bla-blablabla', 'blabla', 'bla-bla-bla-bla', 'bla-bla']
['f', 'f-ff-fff-ffff', 'foo-f']

相关内容

  • 没有找到相关文章

最新更新