【问题标题】:RegEx for three tricky string patterns三个棘手的字符串模式的正则表达式
【发布时间】:2021-06-05 02:19:09
【问题描述】:

我想从个人资料页面中找出 Instagram 用户名。

问题是用户选择如何处理他们的用户名。 (所以,用 RegEx 让计算机得到模式是很棘手的)

我想搜索的所有模式如下所示(用户使用其中一个发布他们的 Instagram 用户名):

  • IG:@用户名
  • IG:@用户名
  • Instagram:@用户名

我想到了下面的这个逻辑,但是我在 RegEx 文档或适合这种搜索的示例中完全迷失了。

我的逻辑:ignorecase (IG or I.G. or I.G or instagram) + (possible space) + (possible :) + (possible space) + (possible @) + (username with - or _ in it) + (以空格或换行符或句号结尾)

总之,我想在“instagram”或​​“IG”或“I.G”之后选择一个单词(用户名),不包括“:”、“@”或空格等不必要的字符。

如何在 RegEx 中执行此操作? One-liner 可能是一个高效而优雅的答案。

附:我想用 Python re 做到这一点。

【问题讨论】:

  • ^(I\.?G\.?|Instagram) ?:? ?@?[-_a-z]+$
  • 谢谢 PM 77-1。但是这个正则表达式是相当固定的。我想找到灵活的模式。它们有或没有空格、连字符下划线或冒号。无论如何,我赞成你的评论。
  • 为什么不只是\b(?:instagram|I\.?G\.?)\s?:?\s?@?(\w+(?:-\w+)*) regex101.com/r/BY6Gyj/1 用户名允许使用哪些字符?

标签: python regex string python-re


【解决方案1】:

我的逻辑:ignorecase(IG or I.G. or I.G. or instagram) + (possible space) + (possible :) + (possible space) + (possible @) + (username with - or _ in it) + (end with空格或换行或句号)

首先,关于前缀部分(IG 和 Instagram :)。您可以在 re.compile 函数上使用 re.Ire.IGNORECASE 参数来忽略 I.G 和 instagram 上的案例。然后在正则表达式中使用|or

r'(instagram|I\.*G\.*)'

然后转义. 并使用问号? 表示它可以有一个或没有,也可以在可能的空格\s 和可能的冒号: 上。

prefix = re.compile(r'(instagram|I\.*G\.*)\s?:?', re.IGNORECASE)

然后是用户名。首先,在@ 上使用问号? 表示它是可选的。然后两个 (.*) 是用户名的第一个和最后一个(如果有)部分,由破折号或下划线(-|_)? 分隔,这也是可选的。 用户名 = re.compile(r'@?(.)(-|_)?(.)\s?$') 完全放置:

username_regex = re.compile(r'^(instagram|I\.?G\.?)\s?:?\s?(@?.*((-|_).*)?\s?)$', re.IGNORECASE)

我已经对此正则表达式进行了一些测试,这是代码。

import re

username_regex = re.compile(r'^(instagram|I\.?G\.?)\s?:?\s?(@?.*((-|_).*)?\s?)$', re.IGNORECASE)

tests = [
    'I.G.: @first-last',
    'I.G: @first-last',
    'I.g: @first-last',
    'I.g.: @first-last',
    'i.G: @first-last',
    'i.G.: @n-last',
    'i.g: @first-last',
    'i.g. @first-last',
    'I.G.:@first-last',
    'I.G@first-last',
    'I.g @first-last',
    'I.gfirst-last',
    'i.G: first_last',
    'i.G. first_last',
    'ig: first_last',
    'i.g. @first-last',
    'inStagram: @first-last',
    'instAgram: @first-last',
    'INSTAGRAM: @first-last',
]

not_matched = 0
for test in tests:
    searched = username_regex.search(test)

    if searched:
        print("MATCH ->", test)
        print(searched.group(), '\n\n')
    else:
        print("========", test)
        not_matched += 1

print(not_matched)
# >> 0

如果要获取前缀和用户名,可以使用group()groups()方法。例如

searched.groups()
# ('I.G:', '@first-last', None, None)

searched.group(0) # 'I.G: @first-last'

# If you want to get the prefix
searched.group(1) # 'I.G:'

# If you want to get the username
searched.group(2) # '@first-last' 

注意:我可能在这里的某个地方错了,如果您发现有问题,请告诉我。谢谢。

【讨论】:

  • 感谢您的回答。它也确实有帮助。但这不会搜索用户名“firstlast”(我的意思是没有 - 或 _)。这是我制作的测试字符串:“Instagram:firstlast”。你能帮我进一步吗?
  • 我忘了在(-|_) 之后添加?。谢谢你,我从我的正则表达式模式中发现了一个错误,当没有 - 或 _ 时,它仍然会在不应该的地方获得姓氏。所以我把它设为((-|_).*)?,所以如果没有分隔符-_,那么它只会得到包含一个单词的名称。
  • 有效!谢谢你。似乎我得到了“user”的整行和“pre”的前缀,所以我需要在用户中替换 pre? (你找到我了吗?)
  • 夏娃,我看到了你的编辑。这是我得到的结果。 instAgram:first-last 在这里,我只想从“搜索”中获取“first-last”。我能做什么?
  • 在我的评论中,我决定将正则表达式 preuser 放在一起,然后我重新组合了前缀和用户名。如果您只想获得“first-last”,请使用searched.group(2)。还是您要求它不应该有@
【解决方案2】:

您可以像这样使用matchgroup

>>> ss = ['IG: @user-name', 'I.G.: @user-name', 'Instagram: @user-name']
>>> m = re.search('(IG|I\.G\.|Instagram)\: @(.*)$', ss[0])
>>> m.group(0)
'IG: @user-name'
>>> m.group(1)
'IG'
>>> m.group(2)
'user-name'
>>> m = re.search('(IG|I\.G\.|Instagram)\: @(.*)$', ss[1])
>>> m.group(2)
'user-name'
>>> m = re.search('(IG|I\.G\.|Instagram)\: @(.*)$', ss[2])
>>> m.group(2)
'user-name'
>>> m = re.search('(IG|I\.G\.|Instagram)\: @(.*)$', 'now for something completely different')
>>> if m:
...   m.group(2)
>>>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2015-11-28
    • 2019-11-09
    • 1970-01-01
    相关资源
    最近更新 更多