正则表达式,用于检查字符串在python中是否至少有一个且最多有3个单词和多个hashtag

2024-10-01 00:24:28 发布

您现在位置:Python中文网/ 问答频道 /正文

s1 = 'Makeupby Antonia #makeup #makeupartist #makeupdolls #abhcosmetics'
s2 = 'Makeupby Antonia asia #makeup #makeupartist #makeupdolls'
s3 = 'Makeupby Antonia'
s4 = '#makeup #makeupartist #makeupdolls #abhcosmetics'  
s5 = 'Makeupby Antonia asia america #makeup #makeupartist'

Regex应该能够匹配s1s2,这仅仅是因为正常的单词数最多为3,并且这些单词有多个hashtag。你知道吗

我可以使用\b(?<![#])[\w]+
选择普通单词 和
我可以使用[#]{1}\w+
选择hashtag 但当我组合这个表达式时,它就起作用了。你知道吗

如何使用这些单独的正则表达式来生成最终的正则表达式,这些正则表达式也可以跟踪计数?你知道吗


Tags: s3单词s4s2s5s1asiahashtag
3条回答

可能有很大的优化空间(可能有依赖项/更少的循环),但这里有一个非regex解决方案,如注释中所述:

s_list = [s1, s2, s3, s4]

def hashtag_words(string_list):
    words = [s.split(" ") for s in string_list]
    hashcounts = [["#" in word for word in wordlist].count(True) for wordlist in words]
    normcounts = [len(wordlist) - hashcount for wordlist, hashcount in zip(words, hashcounts)]
    sel_strings = [s for s, h, n in zip(string_list, hashcounts, normcounts) if h>1 if n in (1,2,3)]
    return sel_strings

hashtag_words(s_list)

>['Makeupby Antonia #makeup #makeupartist #makeupdolls #abhcosmetics',
 'Makeupby Antonia asia #makeup #makeupartist #makeupdolls']

如果我正确理解了您的问题,并且您可以假设单词总是在标记之前,那么您可以使用r'^(\w+ ){1,3}#\w+ #\w+'

for s in ('Makeupby Antonia #makeup #makeupartist #makeupdolls #abhcosmetics',
          'Makeupby Antonia asia #makeup #makeupartist #makeupdolls',
          'Makeupby Antonia',
          '#makeup #makeupartist #makeupdolls #abhcosmetics',  
          'Makeupby Antonia asia america #makeup #makeupartist',):
    print(bool(re.search(r'^(\w+ ){1,3}#\w+ #\w+', s)), s, sep=': ')

这将输出:

True: Makeupby Antonia #makeup #makeupartist #makeupdolls #abhcosmetics
True: Makeupby Antonia asia #makeup #makeupartist #makeupdolls
False: Makeupby Antonia
False: #makeup #makeupartist #makeupdolls #abhcosmetics
False: Makeupby Antonia asia america #makeup #makeupartist

理智的解决方案

将文本拆分为单词,并计算其中有多少以哈希符号开头。你知道吗

def check(text):
    words = text.split()

    num_hashtags = sum(word.startswith('#') for word in words)
    num_words = len(words) - num_hashtags

    return 1 <= num_words <= 3 and num_hashtags > 1
>>> [check(text) for text in [s1,s2,s3,s4]]
[True, True, False, False]

正则表达式解决方案

import re

def check(text):
    pattern = r'(?=.*\b(?<!#)\w+\b)(?!(?:.*\b(?<!#)\w+\b){4})(?:.*#){2}'
    return bool(re.match(pattern, text))

我故意不解释正则表达式,因为我不想你用它。你可能会感到困惑,这应该是一个强烈的迹象,表明这是一个糟糕的代码。你知道吗

相关问题 更多 >