三种棘手的字符串模式的正则表达式

RegEx for three tricky string patterns

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

问题是用户选择如何处理他们的用户名。 (所以,让计算机用正则表达式获取模式是很棘手的)

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

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

我的逻辑:ignorecase (IG or I.G. or I.G or instagram) + (possible space) + (possible :) + (possible space) + (可能是@) + (用户名中有 - 或 _) + (以 space 或换行或句号结尾)

一句话,我想select在“instagram”或​​“IG”或“I.G”之后的一个词(用户名)排除不必要的字符,如“:”,“@” " 或 spaces.

如何在 RegEx 中执行此操作?一行代码可能是一种高效而优雅的答案。

P.S。我想用 Python re.

来做到这一点

My logic: ignorecase(IG or I.G. or I.G or instagram) + (possible space) + (possible :) + (possible space) + (possible @) + (username with - or _ in it) + (ends with space or new line or full stop)

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

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

然后转义 . 并使用问号 ? 表示它可以有一个或 none,也可以 space \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' 

注意:可能我这里有什么地方错了,如果你发现了什么不对的地方,请告诉我。谢谢。

您可以像这样使用 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)
>>>