Python找到所有出现连字符的单词并在位置

时间:2019-06-04 16:39:12

标签: python regex

在本例中,我必须用最后一个标记(例如,c-c-c-c-comeoh-oh-oh-oh,用连字符(comeoh等替换所有出现的模式,其中< / p>

  • 连字符之间的字符数是任意的,可以是一个或多个字符
  • 要匹配的令牌是连字符中的最后一个令牌,因此come中的c-c-come
  • 输入字符串可能出现一次或多次出现,例如以下句子:

    c-c-c-c-come to home today c-c-c-c-come to me

    oh-oh-oh-oh it's a bad life oh-oh-oh-oh

  • 需要通过finditer

    查找匹配令牌的开始和结束位置
    r = re.compile(pattern, flags=re.I | re.X | re.UNICODE)
    for m in r.finditer(text):
       word=m.group()
       characterOffsetBegin=m.start()
       characterOffsetEnd=m.end()
       # now replace and store indexes
    

[更新]

假设那些带连字符的单词不属于固定词典,我在此添加了约束:

  • 连字符之间的字符数必须从最小到最大,例如{1,3},以便捕获组必须与c-comec-c-come匹配,但不能与带连字符的实词匹配例如fine-tuning或类似inter-face

4 个答案:

答案 0 :(得分:4)

您可以使用re.sub()替换所有内容,而不必迭代匹配的索引:

import re

s = 'c-c-c-c-come to home today c-c-c-c-come to me'

print(re.sub(r'(\w+(?:-))+(\w+)', '\\2', s))
# come to home today come to me

答案 1 :(得分:1)

这是一种可能的表达方式:

import re

text = ("c-c-c-c-come to home today c-c-c-c-come to me, "
        "oh-oh-oh-oh it's a bad life oh-oh-oh-oh")
pattern = r"(?<=-)\w+(?=[^-\w])"
r = re.compile(pattern, flags=re.I | re.X | re.UNICODE)
for m in r.finditer(text):
    word = m.group()
    characterOffsetBegin = m.start()
    print(word, characterOffsetBegin)

输出:

come 8
come 35
oh 56

答案 2 :(得分:1)

使用捕获组和反向引用的选项可能是:

(?<!\S)(\w{2,3})(?:-\1)*-(\w+)(?!\S)

这将匹配:

  • (?<!\S)后面是负数,则断言左侧不是非空格字符
  • (\w{2,3})在第1组中捕获一个单词char两次或三次
  • (?:-\1)*重复0次以上以连字符匹配,然后反向引用组1中匹配的内容
  • -(\w+)匹配-,然后匹配第2组中的1个以上的字符字符
  • (?!\S)负向查找,断言右边的内容不是非空格字符

在替换中,使用第二个捕获组\\2r'\2

Regex demo | Python demo

例如

import re

text = "c-c-c-c-come oh-oh-oh-oh it's a bad life oh-oh-oh-oh"
pattern = r"(?<!\S)(\w{1,3})(?:-\1)*-(\w+)(?!\S)"
text = re.sub(pattern, r'\2', text)
print(text)

结果

come oh it's a bad life oh

答案 3 :(得分:0)

可以不用正则表达式来完成。 代码:

s = "c-c-c-c-come to home today c-c-c-c-come to me"
s = " ".join(w if "-" not in w else w[w.rindex('-') + 1:] for w in s.split(" "))

输出:

come to home today come to me