То же регулярное выражение, но разные результаты в Pandas vs. R - PullRequest
1 голос
/ 07 апреля 2019

Рассмотрим это простое регулярное выражение, предназначенное для извлечения заголовков

(\w[\w-]+){2,}

Запуск его в Python (Pandas) по сравнению с R (stringr) дает совершенно разные результаты!

В stringr извлечение работает правильно: посмотрите, как 'this-is-a-very-nice-test' правильно разбирается

library(stringr)
> str_extract_all('stackoverflow.stack.com/read/this-is-a-very-nice-test', 
+                 regex('(\\w[-\\w]+){2,}'))
[[1]]
[1] "stackoverflow"            "stack"                    "read"                     "this-is-a-very-nice-test"

Что ж, в Pandas вывод немного озадачивает

myseries = pd.Series({'text' : 'stackoverflow.stack.com/read/this-is-a-very-nice-test'})

myseries.str.extractall(r'(\w[-\w]+){2,}')
Out[51]: 
             0
     match    
text 0      ow
     1      ck
     2      ad
     3      st

Что здесь не так?

Спасибо!

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Регулярное выражение (\w[-\w]+){2,} представляет группу повторных захватов :

Повторная группа захвата будет захватывать только последнюю итерацию

См. Демонстрационную версию regex , выделенные подстроки - это значения, которые вы получаете в Pandas с .extractall, так как этот метод ожидает " шаблон регулярного выражения с группами захвата"и возвращает" a DataFrame с одной строкой для каждого совпадения и одним столбцом для каждой группы".

В противоположность Пандам extractall, R stringr::str_extract_all опускает все захваченные подстроки в своем результате, и только " извлекает все совпадения и возвращает список векторов символов ".

0 голосов
/ 07 апреля 2019

Это работа, как и ожидалось, после изменения этой части "{2,}" на "{1,}"

import re
s = 'stackoverflow.stack.com/read/this-is-a-very-nice-test'
out = re.findall(r'(\w[-\w]+){1,}', s)
print(out)

вывод:

['stackoverflow', 'stack', 'com', 'read', 'this-is-a-very-nice-test']

РЕДАКТИРОВАТЬ: Объяснение с точки зрения python: повторяющийся квалификатор {m, n}, где m и n - десятичные целые числа.Этот квалификатор означает, что должно быть не менее m повторений, и самое большее n.

в вашем предыдущем примере "{2,}" вы устанавливаете m = 2 и n равны бесконечности, что означает, что шаблон должен повторяться по крайней мере2 раза, но если вы установите m = 1, как в "{1,}", он примет одноразовое вхождение и будет эквивалентно "+", то есть вы можете заменить r '(\ w [- \ w] +){1,} 'to (r' (\ w [- \ w] +) + 'и все равно получите тот же результат

...