python - 为每个单词添加链接,考虑标点符号、缩写和 Unicode

标签 python regex python-2.7

我想为文本中的每个单词添加链接。

示例文本:
"He's <i>certain</i> in America's “West,” it could’ve been possible for gunfights to erupt at any time anywhere," he said holding a gun in his hand.

期望的结果:

"<a href='xxx.com?word=he'>He</a>'s
 <i><a href='xxx.com?word=certain'>certain</a></i>
 <a href='xxx.com?word=in'>in</a>
 <a href='xxx.com?word=america'>America</a>'s
 “<a href='xxx.com?word=west'>West</a>,”
 <a href='xxx.com?word=it'>it</a>
 <a href='xxx.com?word=could'>could</a>'ve
.... etc

(我将输出分成多行,以便于此处阅读。实际输出应该都是一个字符串,例如:

 "<a href='xxx.com?word=he'>He</a>'s <i><a href='xxx.com?word=certain'>certain</a></i> <a href='xxx.com?word=in'>in</a> <a href='xxx.com?word=america'>America</a>'s “<a href='xxx.com?word=west'>West</a>,” <a href='xxx.com?word=it'>it</a> <a href='xxx.com?word=could'>could</a>'ve ... etc

每个单词都应该有一个链接,该链接是单词本身,去掉标点符号和缩写。链接是小写的。标点符号和缩写不应该获得链接。单词和标点符号均为 utf-8,其中包含许多 Unicode 字符。它遇到的唯一 html 元素是 <i></i> ,所以这不是 html 解析,只是一对标签。该链接应该位于 <i> 内的单词上<--> </i>标签。

下面的代码适用于简单的测试用例,但对于较长且具有重复单词的真实文本和 <i> 存在问题。标签:

# -*- coding: utf-8 -*-
import re

def addLinks(s):
    #adds a link to dictionary for every word in text
    link = "xxx.com?word="

    #strip out 's, 'd, 'l, 'm, 've, 're
    #then split on punctuation
    words = filter(None, re.split("[, \-!?:_;\"“”‘’‹›«»]+",  re.sub("'[(s|d|l|m|(ve)|(re)]? ", " ", s)))
    for w in words:
        linkedWord = "<a href=#'" + link + w.lower() + "'>" + w + "</a>"
        s = s.replace(w,linkedWord,1)
    return s

s = """
"I'm <i>certain</i> in America's “West,” it could’ve been possible for gunfights to erupt at any time anywhere," he said holding a gun in his hand.
"""
print addLinks(s)

我的问题:

  • 如何处理句子中重复的单词,无论是完全重复(“in”<->“in”),还是标点符号和/或大写(“He's”<->“he”),或者部分单词(“枪”<->“枪战”,“任何”<->“任何地方”)。如果它精确地按空格分割会更容易,但是通过剥离缩写然后按标点符号分割,我无法弄清楚如何干净地将链接的单词替换回字符串中。
  • 我的消除缩写的正则表达式适用于“m”和“d”等单个字母,但不适用于“ve”和“re”。
  • 我不知道如何处理 <i>标签,例如 <i>certain</i>进入<i><a href="xxx.com?word=certain">certain</a></i>

我在 Python 2.7 中执行此操作,但是 this answer for javascript 类似,并且可以使用 Unicode,但不能解决我的标点符号等问题。

最佳答案

正则表达式可以帮助您。

要匹配任何长度的单词,您可以使用 \w+ 。忽略单个标签 <i></i> ,您可以添加前瞻: (?!>) 。这将匹配开始和结束标记。最后,要忽略右侧的缩写,您可以在匹配正确之前添加一个lookbehind:(?<!') .

要插入找到的模式的小写版本,请使用回调函数(来自 Using a regular expression to replace upper case repeated letters in python with a single lowercase letter )。回调 lambda 函数插入找到的匹配项的小写版本,周围是 <a=代码,并立即构建整个替换字符串。

这引导我们

import re

s = """
"I'm <i>certain</i> in America's “West,” it could’ve been possible for gunfights
to erupt at any time anywhere," he said holding a gun in his hand.
"""

callback = lambda pat: '<a href="xxx.com?word='+pat.group(1).lower()+'">'+pat.group(1)+'</a>'
result = re.sub(r"(?<!')(?!i>)(\w+)", callback, s)

哪里result最终将成为

"<a href="xxx.com?word=i">I</a>'m <i><a href="xxx.com?word=certain">
certain</a></i> <a href="xxx.com?word=in">in</a> <a href="xxx.com?
word=america">America</a>'s "<a href="xxx.com?word=west">West</a>," ...

关于python - 为每个单词添加链接,考虑标点符号、缩写和 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37132804/

相关文章:

python - 你如何让 SQLAlchemy 覆盖 MySQL "on update CURRENT_TIMESTAMP"

python - 在 YAML 中执行算术运算?

mysql - MySQL 的 SED 等效项

c++ - 将读取行与正则表达式进行比较

python - 有效地找到实体计数 Google App Engine

python - Python 中的二维颜色图

Javascript正则表达式奇怪的行为 String.match()

python - 提取维基百科中的所有城市

python - 从命名空间创建命名元组?

Python - 使用时间戳、timedelta 进行日期和时间比较