2013-12-17 3 views
3

Короткий вопрос:Python регулярное выражение: матч всех последующих заглавных букв

У меня есть строка:

title="Announcing Elasticsearch.js For Node.js And The Browser" 

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

Таким образом, ожидаемый результат должен быть:

['Announcing Elasticsearch.js', 'Elasticsearch.js For', 'For Node.js', 'Node.js And', 'And The', 'The Browser'] 

То, что я сейчас это:

'[A-Z][a-z]+[\s-][A-Z][a-z.]*' 

Это дает мне выход:

['Announcing Elasticsearch.js', 'For Node.js', 'And The'] 

Как я могу изменить мое регулярное выражение, чтобы дать желаемый результат?

+1

Возможно, связано: http://stackoverflow.com/q/15799332/1578604 – Jerry

+0

Похоже, вы хотите переместить последнее совпадающее положение слова назад. Хорошо ли получить пары в два раза, а не все сразу? – mtanti

+0

@mtanti Я думаю, что должно быть ОК, я буду разбирать только 5-7 строк слов. –

ответ

2

Вы можете использовать это:

#!/usr/bin/python 
import re 

title="Announcing Elasticsearch.js For Node.js And The Browser TEst" 
pattern = r'(?=((?<![A-Za-z.])[A-Z][a-z.]*[\s-][A-Z][a-z.]*))' 

print re.findall(pattern, title) 

А "нормальный" шаблон не может соответствовать перекрывающихся подстроки , все символы основаны раз и навсегда. Однако внешний вид (?=..) (т. Е. «За которым следует») является только проверкой и ничего не соответствует. Он может разбирать строку несколько раз. Таким образом, если вы помещаете группу захвата в просмотр, вы можете получить перекрывающиеся подстроки.

+0

Можете ли вы объяснить немного больше, как это работает? Может быть, многословная версия? –

+1

Вот объяснение подробно: http://regex101.com/r/xE2vT0 – brandonscript

0

Там, наверное, более эффективный способ сделать это, но вы можете использовать регулярные выражения, как это:

(\b[A-Z][a-z.-]+\b) 

Затем перебирать группы захвата как и тестирование с этим регулярным выражением: (^[A-Z][a-z.-]+$) обеспечить согласованную группу (current) соответствует соответствующей группе (далее).

Рабочий пример:

import re 

title = "Announcing Elasticsearch.js For Node.js And The Browser" 
matchlist = [] 
m = re.findall(r"(\b[A-Z][a-z.-]+\b)", title) 
i = 1 
if m: 
    for i in range(len(m)): 
     if re.match(r"(^[A-Z][a-z.-]+$)", m[i - 1]) and re.match(r"(^[A-Z][a-z.-]+$)", m[i]): 
      matchlist.append([m[i - 1], m[i]]) 

print matchlist 

Выход:

[ 
    ['Browser', 'Announcing'], 
    ['Announcing', 'Elasticsearch.js'], 
    ['Elasticsearch.js', 'For'], 
    ['For', 'Node.js'], 
    ['Node.js', 'And'], 
    ['And', 'The'], 
    ['The', 'Browser'] 
] 
0

Если ваш код Python на данный момент это

title="Announcing Elasticsearch.js For Node.js And The Browser" 
results = re.findall("[A-Z][a-z]+[\s-][A-Z][a-z.]*", title) 

тогда программа пропускает нечетные пары. Простым решением было бы исследовать образец после пропуска первого слова, как это:

m = re.match("[A-Z][a-z]+[\s-]", title) 
title_without_first_word = title[m.end():] 
results2 = re.findall("[A-Z][a-z]+[\s-][A-Z][a-z.]*", title_without_first_word) 

Теперь просто объединить результаты и result2 вместе.

 Смежные вопросы

  • Нет связанных вопросов^_^