python - 使用 python 进行正则表达式处理
问题描述
我正在尝试学习 python 并同时使用 NLTK 进行文本分析。
我在文本分析之前使用 python 来擦洗文本。
给定句子:The target IP was: 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
所以看着我发现了一个正则表达式,它可以做我想要的,有点...... Wiktor Stribiżew 的 RegEx
re.sub(r'[]!"$%&\'()*+,./:;=#@?[\\^_`{|}~-]+', r' \g<0> ', my_text).strip()
我能够弄清楚发生了什么,但是在这种形式中,它分隔了所有标点符号,即使在单词中间也是如此。例如,它将今天的日期从: 转换
6/28/2109
为"6 / 28 / 2019"
。
所以我修改为在开始/结束时使用锚标签,但似乎我必须运行它两次,一次用于开始标点符号,另一次用于结束。似乎效率很低,并希望有人可以展示正确的方法来完成此任务。下面的代码是正则表达式版本:
def sep_punct_by_regex(sent)->list :
words = sent.split(" ")
new_words = []
for w in words:
tmp1 = re.sub(r'^[]!"$/%&\'()*+,.:;=#@?[\\^_`{|}~-]+', r' \g<0> ', w).strip()
tmp2 = re.sub(r'[]!"$/%&\'()*+,.:;=#@?[\\^_`{|}~-]+$', r' \g<0> ', tmp1).strip()
t = tmp2.split(" ")
for x in t:
new_words.append(x)
return new_words
请注意^
tmp1 和$
tmp2 中的 照原样工作,但目标是在构建时学习,那么我将如何修改 RegEx 以进行单次传递?我在前面尝试了明显的 ( ^
) ,最后尝试了$
,但它不起作用。
解决方案
您可以使用
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]|[1-9]?[0-9])){3}\b
- IPv4 正则表达式模式|
- 或者[^\W_]+
- 一个或多个字母或数字|
- 或者(?:[^\w\s]|_)+
- 一个或多个除 word 和空格字符或_
.
推荐阅读
- java - 应该在主线程之外调用 getExternalCacheDir() 吗?
- java - 单独的容器和 Shiro 会话?
- html - HTML5 输入模式要求第一个字符必须是正斜杠
- ios - AVAudioFile (Mac/iOS) : 将音频编码为恒定比特率 AAC
- python - 在 python 列表中分离和计算表情符号
- javascript - 标题太长 将菜单按钮滑动到卡片右侧
- c# - 使用 .Net Core 3.1 运行 XSLT 2.0
- sql - 使用 ssis 从 excel 加载数据时意外终止
- c# - 如何在 c# 的日期时间选择器中添加秒数?
- r - 评估另一个表中是否不存在某个值