用python处理正则表达式

用python处理正则表达式,python,regex,nlp,Python,Regex,Nlp,我正在尝试学习python,同时使用NLTK进行文本分析 我正在使用python在文本分析之前清除文本 给出以下句子:目标IP是:127.1.1.100。 我想将其标记为: ["The", "target", "IP", "was", ":","127.1.1.100","."] 保留所有标点符号以重建源文档很重要,但我需要分隔前导/尾随标点符号,以便对单个单词进行文本分析。我编写了下面的python代码,它工作得很好,但似乎有点笨拙 punct = ['.', ',', ':', ';',

我正在尝试学习python,同时使用NLTK进行文本分析

我正在使用python在文本分析之前清除文本

给出以下句子:
目标IP是:127.1.1.100。

我想将其标记为:

["The", "target", "IP", "was", ":","127.1.1.100","."]
保留所有标点符号以重建源文档很重要,但我需要分隔前导/尾随标点符号,以便对单个单词进行文本分析。我编写了下面的python代码,它工作得很好,但似乎有点笨拙

punct = ['.', ',', ':', ';', '!', '[', ']', '(', ')', '{', '}']
def split_punctuation(sentence)-> list:
    sentwords = sentence.split(" ")
    for i, word in enumerate(sentwords):
        if word_ends_with_punct(word) and len(word) > 1:
            sentwords.pop(i)
            sentwords.insert(i, word[:-1])
            sentwords.insert(i+1, word[-1])
            word = word[:-1]
        if word_starts_with_punct(word) and len(word) > 1:
            sentwords.pop(i)
            sentwords.insert(i, word[0:1])
            sentwords.insert(i+1, word[1:])
            word = word[1:]
    return sentwords

def word_starts_with_punct(w)-> bool:
    for p in punct:
        if w.startswith(p):
            return True
    return False

def word_ends_with_punct(w)->bool:
    for p in punct:
        if w.endswith(p):
            return True
    return False
所以我发现了一个正则表达式,它能满足我的需要,有点。。。

注意tmp1中的
^
,以及tmp2中的
$
这可以按原样工作,但目标是在构建过程中学习,因此如何修改单通道的正则表达式?我在前面尝试了明显的(
^
),在最后尝试了
$
,但没有成功

您可以使用

re.findall(r'\b(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\b|[^\W_]+|(?:[^\w\s]|_)+', s)

要删除字符串两端的标点符号并去除空白,请使用

re.sub(r'^[\W_]+|[\W_]+$', '', s).strip()
所以,它看起来像

s = re.sub(r'^[\W_]+|[\W_]+$', '', s).strip()
oct = r'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
return re.findall(r'\b{0}(?:\.{0}){{3}}\b|[^\W_]+|(?:[^\w\s]|_)+'.format(oct), s)
详细信息

  • \b(?:25[0-5]| 2[0-4][0-9]| 1[0-9][0-9]|[1-9]?[0-9])(?:\(?:25[0-5]| 2[0-4][0-9]| 1[0-9][0-9]?[0-9]){3}\b
  • |
    -或
  • [^\W\u]+
    -一个或多个字母或数字
  • |
    -或
  • (?:[^\w\s]|)+
    -一个或多个字符,而不是单词和空格字符或

这里有3层。字母,一些标点符号,一些数字+一些标点符号。我不认为你能轻易地将其标记化。你必须为此制定一套极端的规则。我想我不清楚我的要求,对不起。我需要检查文档中的每个单词,并删除任何前导/尾随标点符号。不只是IP,还是没有乐趣。输入句子:“恶意软件分析报告(MAR)-10135536-F”,我所期望的是[“恶意软件”,“分析”,“报告”,“报告”(“,“MAR”,”,“-”,“10135536-F”),我得到的是:[“恶意软件”,“分析”,“报告”,“MAR”,“-”,“10135536-F”]。特别是,MAR周围的()应该是单独的标记。谢谢你的关注@特别是GeoffWillis,
Mar
作为单独的代币。你在测试什么代码?你确定你的要求吗?也许这是一个更好的解决方案,但我现在不确定。很抱歉这么密集,但我真的不完全理解你发布的内容。要求是一句一句地浏览文档,然后逐字浏览。对于每个单词,确保没有前导/尾随标点符号。我以IP为例,但也使用了(MAR)->[“(”,“MAR”,”)]。我已经发布了我的代码,我想你想让我用它来代替我的regEx。请注意,这两个注释掉了regEx是你的,而且效果很好,但我一直在尝试一次通过。[link][link]不知道为什么这个404是从这里开始的,在浏览器中剪切粘贴效果很好。。。
re.sub(r'^[\W_]+|[\W_]+$', '', s).strip()
s = re.sub(r'^[\W_]+|[\W_]+$', '', s).strip()
oct = r'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
return re.findall(r'\b{0}(?:\.{0}){{3}}\b|[^\W_]+|(?:[^\w\s]|_)+'.format(oct), s)