Одно и то же регулярное выражение, но разные результаты в Pandas и R

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

(\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"

В пандах ну вывод немного озадачивает

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

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

Спасибо!

Вы тоже не ожидаете "com"?

cs95 07.04.2019 22:10

Может быть myseries.str.extractall(r'(\w[-\w]*)') и str_extract_all('stackoverflow.stack.com/read/this-is-a-very‌​-nice-test', regex('(\\w[-\\w]*)')) или иметь {1,}

akrun 07.04.2019 22:12

Технически myseries.str.extractall(r'([\w-]+)') дает то, что вы ищете, хотя вы не можете избежать сопоставления текста, который начинается с дефиса (чтобы избежать этого, используйте r'(\w[\w-]+)')

cs95 07.04.2019 22:13

спасибо, но я не понимаю несоответствия!

ℕʘʘḆḽḘ 07.04.2019 22:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
128
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это работает, как и ожидалось, после изменения этой части "{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, }' в (r'(\w[-\w]+)+' и все равно получить тот же результат

спасибо, я знаю, что я думаю, что моя точка зрения заключается в том, почему одно и то же регулярное выражение возвращает разные результаты

ℕʘʘḆḽḘ 07.04.2019 23:01
Ответ принят как подходящий

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

The repeated capturing group will capture only the last iteration

См. демонстрация регулярных выражений, выделенные подстроки — это значения, которые вы получаете в Pandas с помощью .extractall, поскольку этот метод ожидает «шаблон регулярного выражения с захватом групп» и возвращает «DataFrame с одной строкой для каждого совпадения и одним столбцом для каждой группы».

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

@ ℕʘʘḆḽḘ Чтобы шаблон работал в обеих средах, используйте (\w[\w-]{3,}), поскольку именно это означает ваш текущий шаблон: извлеките все слова, которые начинаются со слова char, а затем содержат 3 или более слов или символов дефиса. Если это не то, что вы хотели, и вам нужно исправить, сообщите о реальных требованиях.

Wiktor Stribiżew 07.04.2019 23:11

Спасибо!! что-то я не понимаю, это разница между захваченными подстроками и совпадениями

ℕʘʘḆḽḘ 07.04.2019 23:23

@ℕʘʘḆḽḘ Захваченные подстроки — это те, которые сопоставляются с частями шаблона в скобках. Целые совпадения — это строки, совпадающие со всем шаблоном. См. ссылку группы захвата.

Wiktor Stribiżew 07.04.2019 23:33

Другие вопросы по теме