Py学习  »  Python

正则表达式与python 3中以下划线开头和结尾的单词匹配

azawalich • 7 年前 • 2331 次点击  

我有下面的示例代码,我试图匹配所有正在启动的word实例 结束 带下划线(单下划线或双下划线)。

import re
test = ['abc text_ abc',
'abc _text abc',
'abc text_textUnderscored abc',
'abc :_text abc', 
'abc _text_ abc', 
'abc __text__ abc',
'abc _text_: abc',
'abc (-_-) abc']
test_str = ' '.join(test)
print(re.compile('(_\\w+\\b)').split(test_str))

我已经试过下面的正则表达式,它看起来太强了(应该只匹配 _text_ 和 __text__ )

输出: ['abc text_ abc abc ', '_text', ' abc abc text', '_textUnderscored', ' abc abc :', '_text', ' abc abc ', '_text_', ' abc abc ', '__text__', ' abc abc ', '_text_', ': abc abc (-_-) abc']

你能建议一个更好的方法吗(最好是使用单一的regex模式和 re.split 方法?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43184
文章 [ 2 ]  |  最新文章 7 年前
altskop
Reply   •   1 楼
altskop    7 年前

您甚至不需要使用regex,最有效的方法是将字符串拆分为单词,然后检查它是否以下划线开头和结尾。

def get_underscored(text):
    for word in text.split():
        if word.startswith("_") and word.endswith("_"):
            yield word

test = ['abc text_ abc',
'abc _text abc,',
'abc text_textUnderscored abc',
'abc :_text abc',
'abc _text_ abc',
'abc __text__ abc']
test_str = ' '.join(test)
print(list(get_underscored(test_str)))

结果是 ['_text_', '__text__'] .

尽管这种方法在较大的输入上的伸缩性不如regex,但在较小的输入上的伸缩性要快几个数量级。

Wiktor Stribiżew
Reply   •   2 楼
Wiktor Stribiżew    7 年前

如果您要匹配任何字符块(字母、数字和下划线),而这些字符块的前面或后面没有非单词字符(字母、数字和下划线以外的字符)和任何长度(甚至是1, _ )你可以用

r'\b_(?:\w*_)?\b'

具有 re.findall . 见 regex demo .

如果不想匹配单字符单词(即 γ )您需要删除可选的非捕获组,并使用 r'\b_\w*_\b' .

如果需要匹配至少3个字符的单词,也可以替换 * (零次或多次重复) + (一次或多次发生)。

如果仅当单词位于字符串的开头/结尾或后跟/前面有空格时才将其视为完整单词,请替换 \b...\b 具有 (?<!\S)...(?!\S) :

r'(?<!\S)_\w*_(?!\S)'

见 another regex demo

细节

  • \b -一个字的边界,必须有一个字符串的开头或一个非字的字符
  • γ -下划线
  • (?:\w*_)? -一个可选的非捕获组,与
    • \w* -0+字字符(字母、数字, γ (感谢这个可选的组,甚至 γ 将找到单词)
    • γ -下划线
  • \b -单词边界,后面必须有字符串结尾或非单词字符
  • (?<!\S) -左空白边界
  • (?!\S) -右空白边界

见 Python demo :

rx = re.compile(r'\b_(?:\w*_)?\b')
print(rx.findall(test_str))
# => ['_text_', '__text__']