使用regex提取两个下划线之前的文本

rqqzpn5f  于 2023-01-18  发布在  其他
关注(0)|答案(2)|浏览(163)

我觉得我离解决方案不远了,但我仍然很难用Regex从变量中提取一些文本。条件是:

  • 文本只能包含大写字符或整数
  • 文本可以包含下划线,但不能包含两个连续的下划线

示例:

test_TEST_TEST_1_TEST_13DAHA bfd     -->   TEST_TEST_1_TEST_13DAHA
test_TEST_TEST_1_TEST__13DAHA bfd    -->   TEST_TEST_1_TEST
test__TEST_TEST                      -->   TEST_TEST
test_TEST__DHJF                      -->   TEST
test_TEST__Ddsa                      -->   TEST
test__TEST                           -->   TEST

到目前为止,我得到了
_([0-9A-Z_]+)适用于第一个而不是第二个
_([0-9A-Z_]+)(?:__.*)+适用于第二个而不是第一个

omqzjyyz

omqzjyyz1#

如果之前已经匹配了某个字符串,那么你就不需要两个下划线后面的字符串,也就是说,在捕获了预期的模式之后,你可能会使用并省略两个或更多下划线后面的所有字母/数字:

_([0-9A-Z]+(?:_[0-9A-Z]+)*)(?:__[0-9A-Z_]+)?

请参阅regex demo(?:__[0-9A-Z_]+)?部分"排除"试图匹配紧接在您匹配之后的文本。
您需要获取Group 1的值而不是整个匹配值,因此re.findall最适合这里,特别是当您期望多个匹配时。如果您期望每个字符串有一个匹配,请使用re.search
请参见Python demo

import re
cases = ["test_TEST bfd",
    "test_TEST_TEST_1_TEST_13DAHA bfd",
    "test_TEST_TEST_1_TEST__13DAHA bfd",
    "test__TEST_TEST",
    "test_TEST__DHJF",
    "test_TEST__Ddsa"
]
pattern = re.compile(r'_([0-9A-Z]+(?:_[0-9A-Z]+)*)(?:__[0-9A-Z_]+)?')
for case in cases:
    matches = pattern.findall(case)
    print(matches)

With re.search

for case in cases:
    match = pattern.search(case)
    if match:
        print(match.group(1))

输出:

TEST
TEST_TEST_1_TEST_13DAHA
TEST_TEST_1_TEST
TEST_TEST
TEST
TEST
3htmauhk

3htmauhk2#

使用此模式:

[A-Z0-9]+(?=_)(?:_[A-Z0-9]+)*

示例脚本:

inp = ["test_TEST_TEST_1_TEST_13DAHA bfd", "test_TEST_TEST_1_TEST__13DAHA bfd", "test__TEST_TEST", "test_TEST__DHJF"]
for i in inp:
    matches = re.findall(r'[A-Z0-9]+(?=_)(?:_[A-Z0-9]+)*', i)
    print(i + " => " + matches[0])

这将打印:

test_TEST_TEST_1_TEST_13DAHA bfd => TEST_TEST_1_TEST_13DAHA
test_TEST_TEST_1_TEST__13DAHA bfd => TEST_TEST_1_TEST
test__TEST_TEST => TEST_TEST
test_TEST__DHJF => TEST

相关问题