令牌化输入字符串python

时间:2014-11-25 19:55:15

标签: python regex

好的,所以我要求一个跟进问题来标记字符串。它几乎正常,但是我错过了这个边缘案例。

现在我的职能是:

def tokenize(text):
    return re.findall('[\\!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~]|\w+', text)

除了输入外,它几乎完成了我想做的事情:

>>> tokenize('Break/\\ is almost? ? soon')
Output: ['Break', '/','is', 'almost', '?', '?', 'soon']

Expected Output:
['Break', '/', '\\', 'is', 'almost', '?', '?', 'soon']

我猜它与逃避有关,但我认为我在我的正则表达式中匹配它。有什么建议?

2 个答案:

答案 0 :(得分:2)

您的问题是您的字符类中唯一的反斜杠被解释为转义字符。 \\!由Python解析为\!,然后由regexp引擎解析为转义!。同样,\\]由Python解析为\],然后由regexp引擎解析为转义]。所以,没有什么可以匹配反斜杠。

您可以双重转义第一个反斜杠,因此\\\\!将被Python解析为\\!,然后由正则表达式引擎解析为\后跟! }。当然,您将单独留下\\],因为您想要将其解析为转义]。你也想在w之前逃避反斜杠;你碰巧逃脱了那个因为Python(至少从2.7和3.4开始)没有\w转义序列,但是依靠它并不是一个好主意。

但实际上,如果你使用raw string literals来防止Python解释任何反斜杠,你的生活将会轻松得多,所以你知道它们都会进入正则表达式引擎。这在Regular Expression HOWTO

中有解释
re.findall(r'[\\!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~]|\w+', text)

现在,Python没有触及\\!,因此regexp引擎将其解释为文字\!。另请注意,我在]之前删除了双反斜杠,因为想要逃避那个反斜杠,我们希望它逃脱]

[\\!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~]|\w+

Regular expression visualization

Debuggex Demo

答案 1 :(得分:0)

关闭主题,但这也有效

list(filter(str.strip,re.split('(\W)','Break/\\ is almost? ? soon')))