繁体   English   中英

正则表达式finditer:在相同的符号上搜索两次

[英]Regular expression finditer: search twice on the same symbols

我需要在文本中找到匹配并获得其位置。 例如,我必须在文本中找到“你好你好”。 当文本是“hello hello world hello hello”时,没关系,我得到0-11和18-29的位置。 但是当文本是“hello hello hello world”时,我只得到一个位置 - 0-11。 但我必须找到两者(0-11和6-17)。 我的意思是,我明白了

  1. 你好你好你好世界

但必须得到

  1. 你好你好你好世界

  2. 你好你好你好世界

在另一个案例中,我必须找到复杂的模式:“你好1,2美丽的世界” - 这意味着在“你好”和“美丽”这两个词之间可以是一两个词,而在“美丽”和“世界”2,3或4个字。 我必须找到所有的组合。

这是模式: re.compile(u'(^|[\\[\\]\\/\\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@])(hello)(([\\[\\]\\/\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@%]+[a-zA-Zа-яА-Я$]+(-[a-zA-Zа-яА-Я$]+)*){1,2}[\\[\\]\\/\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@%]*)(beautiful)(([\\[\\]\\/\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@%]+[a-zA-Zа-яА-Я$]+(-[a-zA-Zа-яА-Я$]+)*){2,4}[\\[\\]\\/\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@%]*)(world)($|[\\[\\]\\/\\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)\\{\\} !<>:;,#@])')

而文字是“你好非常美丽的非常大的世界”。 我可以得到唯一的组合,但需要得到4:

  1. 你好非常美丽非常大的世界世界

  2. 你好非常靓丽非常大的世界世界

  3. 你好非常美丽非常大的世界世界

  4. 你好非常靓丽非常大的世界世界

当比赛相互交叉时,如何获得比赛的所有组合?

国旗re.DOTALL没有帮助。

import re

patterns = [
    u'(hello)(( [a-z]+ *){1,2})(beautiful)(( [a-z]+ *){2,4})(world)',
    u'hello hello'
]
text = u'hello hello hello world hello very beautiful beautiful very big world world'
for p in patterns:
    print p
    c = re.compile(p, flags=re.I+re.U)
    for m in c.finditer(text):
        print m.start(), m.end()

结果是

>>> (hello)(( [a-z]+ *){1,2})(beautiful)(( [a-z]+ *){2,4})(world)
>>> 24 69
(need 24 69 and 24 69 and 24 75 and 24 75 - because there are two positions of the word "beautiful")
>>> hello hello
>>> 0 11
(need 0 11 and 6 17)

这些模式的真实例子是:

u“выйдитенаулицы”,u“избавить。*от”,u“смотритесмотрите”,u“смеят。*”

和距离:

имени0,3ленина

целых0,5лет。*

целых0,5лет。*0,1назад

UPD

变体u'(?=(hello hello))有助于图案之间没有距离。 但是如何在距离模式中使用它,例如(hello) (?:[a-zA-Zа-яА-Я]+ ){1,2}(beautiful) (?:[a-zA-Zа-яА-Я]+ ){2,4}(world)

我认为你可以尝试下面的表达而不是正则表达式,看起来不是那么好,但可能会解决你的问题:

表达:

 [pos for pos, char in enumerate(string) if string[pos:].find(pattern) == 0]

它为列表输出提供了模式在字符串中的位置。

In [43]: string = "hello very beautiful beautiful very big world world"
In [44]: pattern='hello'
In [45]: [pos for pos, char in enumerate(string) if string[pos:].find(pattern) == 0]
Out[45]: [0]
In [46]: pattern='very'
In [47]: [pos for pos, char in enumerate(string) if string[pos:].find(pattern) == 0]
Out[47]: [6, 31]
In [48]: pattern='world'
In [49]: [pos for pos, char in enumerate(string) if string[pos:].find(pattern) == 0]
Out[49]: [40, 46]
In [50]: pattern='very big'
In [51]: [pos for pos, char in enumerate(string) if string[pos:].find(pattern) == 0]
Out[51]: [31]

希望这可以帮助。

你的问题仍然没有明确你想做什么,但我会抓住它:

正则表达式在没有消费的情况下找到重复:

([a-zA-Zа-яА-Я]+)(?= (\1))

正则表达式找到hello beautifulworld的特定数量的单词之间:

(hello) (?:[a-zA-Zа-яА-Я]+ ){1,2}(beautiful) (?:[a-zA-Zа-яА-Я]+ ){2,4}(world)

最后更新

您想要做的事情是在一次运行中不能完全在正则表达式中完成。

更容易循环并执行不同的正则表达式:

for i in range(1,3):
    for j in range(2,5):
        regStr='(hello) (?:\w+ ){' + str(i) + '}(beautiful) (?:\w+ ){' + str(j) +'}(world)'

然后使用再次检查重复项

([a-zA-Zа-яА-Я]+)(?= (\1))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM