Поддерживают ли регулярные выражения Python что-то вроде Perl's \ G? - PullRequest
5 голосов
/ 09 февраля 2009

У меня есть регулярное выражение Perl (показано здесь , хотя для ответа на этот вопрос, надеюсь, понимание всего не требуется), которое содержит метасимвол \ G. Я хотел бы перевести его на Python, но Python, похоже, не поддерживает \ G. Что я могу сделать?

Ответы [ 5 ]

4 голосов
/ 09 февраля 2009

Попробуйте это:

import re
re.sub()
re.findall()
re.finditer()

например:

# Finds all words of length 3 or 4
s = "the quick brown fox jumped over the lazy dogs."
print re.findall(r'\b\w{3,4}\b', s)

# prints ['the','fox','over','the','lazy','dogs']
2 голосов
/ 27 августа 2010

Я знаю, что немного опоздал, но вот альтернатива подходу \G:

import re

def replace(match):
    if match.group(0)[0] == '/': return match.group(0)
    else: return '<' + match.group(0) + '>'

source = '''http://a.com http://b.com
//http://etc.'''

pattern = re.compile(r'(?m)^//.*$|http://\S+')
result = re.sub(pattern, replace, source)
print(result)

вывод (через Ideone ):

<http://a.com> <http://b.com>
//http://etc.

Идея состоит в том, чтобы использовать регулярное выражение, соответствующее обоим видам строк: URL или закомментированная строка. Затем вы используете обратный вызов (делегат, замыкание, встроенный код и т. Д.), Чтобы выяснить, какой из них соответствует, и вернуть соответствующую строку замены.

На самом деле, это мой предпочтительный подход даже в тех вариантах, которые поддерживают \G. Даже в Java, где я должен написать кучу стандартного кода для реализации обратного вызова.

(Я не парень из Python, поэтому прости меня, если код ужасно непитоничен.)

2 голосов
/ 10 февраля 2009

Python не имеет модификатора / g для своего регулярного выражения, и поэтому не имеет токена \ G регулярного выражения. Жаль, правда.

2 голосов
/ 10 февраля 2009

Вы можете использовать re.match для соответствия закрепленным шаблонам. re.match будет соответствовать только в начале (позиция 0) текста или там, где вы указали.

def match_sequence(pattern,text,pos=0):
  pat = re.compile(pattern)
  match = pat.match(text,pos)
  while match:
    yield match
    if match.end() == pos:
      break # infinite loop otherwise
    pos = match.end()
    match = pat.match(text,pos)

Это будет соответствовать шаблону только с заданной позиции, и любые совпадения, которые следуют после 0 символов после.

>>> for match in match_sequence(r'[^\W\d]+|\d+',"he11o world!"):
...   print match.group()
...
he
11
o
0 голосов
/ 10 февраля 2009

Не пытайтесь объединить все в одно выражение, так как его становится очень трудно читать, переводить (как вы сами видите) и поддерживать.

import re
lines = [re.sub(r'http://[^\s]+', r'<\g<0>>', line) for line in text_block.splitlines() if not line.startedwith('//')]
print '\n'.join(lines)

Python обычно не лучший, когда вы буквально переводите с Perl, у него есть свои собственные шаблоны программирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...