Рассмотрим это простое регулярное выражение, предназначенное для извлечения заголовков.
(\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
Что здесь не так?
Спасибо!
Может быть myseries.str.extractall(r'(\w[-\w]*)')
и str_extract_all('stackoverflow.stack.com/read/this-is-a-very-nice-test', regex('(\\w[-\\w]*)'))
или иметь {1,}
Технически myseries.str.extractall(r'([\w-]+)')
дает то, что вы ищете, хотя вы не можете избежать сопоставления текста, который начинается с дефиса (чтобы избежать этого, используйте r'(\w[\w-]+)'
)
спасибо, но я не понимаю несоответствия!
Это работает, как и ожидалось, после изменения этой части "{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]+)+' и все равно получить тот же результат
спасибо, я знаю, что я думаю, что моя точка зрения заключается в том, почему одно и то же регулярное выражение возвращает разные результаты
Регулярное выражение (\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 или более слов или символов дефиса. Если это не то, что вы хотели, и вам нужно исправить, сообщите о реальных требованиях.
Спасибо!! что-то я не понимаю, это разница между захваченными подстроками и совпадениями
@ℕʘʘḆḽḘ Захваченные подстроки — это те, которые сопоставляются с частями шаблона в скобках. Целые совпадения — это строки, совпадающие со всем шаблоном. См. ссылку группы захвата.
Вы тоже не ожидаете "com"?