У меня есть регулярное выражение, которое выглядит так, чтобы извлечь номера заказов из столбцов:
df["Orders"].str.extract('([0-9]{9,10}[/+ #_;.-]?)')
Колонка заказов может выглядеть так:
12
123456789
1234567890
123456789/1234567890
123456789/1/123456789
123456789+1234567890
Результирующий новый столбец в фрейме данных после регулярного выражения должен выглядеть так:
NaN
123456789
1234567890
123456789/1234567890
123456789/123456789
123456789+1234567890
Однако с моим текущим регулярным выражением я получаю следующий результат:
NaN
123456789
1234567890
123456789/
123456789/
123456789+
Как я могу получить результат, который я ищу?
@ j1-lee заказы, идущие после косой черты, знаков плюса, хэштегов и т. д., которые соответствуют 9 или 10 цифрам, на самом деле являются заказами. Затем они в конечном итоге будут взорваны, чтобы создать множество разных рядов.






Ты можешь использовать
import pandas as pd
df = pd.DataFrame({'Orders':['12','123456789','1234567890','123456789/1234567890','123456789/1/123456789','123456789+1234567890', 'Order number: 6508955960_000010_1005500']})
df["Result"] = df["Orders"].str.findall(r'[/+ #_;.-]?(?<![0-9])[0-9]{9,10}(?![0-9])').str.join('').str.lstrip('/+ #_;.-')
df.loc[df['Result'] == '', 'Result'] = np.nan
См. демонстрация регулярных выражений. Подробности
[/+ #_;.-]?(?<![0-9])[0-9]{9,10}(?![0-9]) - соответствует необязательным символам /, +, пробелу, #, _, ;, . или -, а затем ни одному или десятизначному числу, не заключенному в другие цифрыSeries.str.findall извлекает все вхождения.str.join('') объединяет совпадения в одну строку.str.lstrip('/+ #_;.-') - удаляет специальные символы, совпавшие с числом в начале строкиdf.loc[df['Result'] == '', 'Result'] = np.nan - при необходимости - заменяет пустые строки значениями np.nan в столбце Result.Выход:
>>> df
Orders Result
0 NaN NaN
1 123456789 123456789
2 1234567890 1234567890
3 123456789/1234567890 123456789/1234567890
4 123456789/1/123456789 123456789/123456789
5 123456789+1234567890 123456789+1234567890
>>>
Хм, что-то вроде этого: Order number: 6508955960_000010_1005500 возвращает пробел... Это должно вернуть 6508955960
@user2896120 user2896120 Переключиться на числовые границы.
Спасибо, это исправляет это, есть ли способ удалить ведущий #,+,etc., чтобы он удалил что-то вроде # 6508955960 в регулярном выражении? Или было бы проще сделать ltrim
@user2896120 user2896120 Регулярное выражение усложняет сопоставление с образцом. Я бы просто использовал lstrip
Вы можете адаптировать следующий код для работы с фреймами данных,
Регулярное выражение: (?:^|([/+ #_;.-]))(?:\d{1,8})(?!\d)
(?:\d{1,8})(?!\d) - найти число (<9 цифр)([/+ #_;.-]) - перед ним стоит один или ни один из возможных разделителей (группа №1)Условно замените на NaN или пустую строку — subst использует match.group(1), чтобы различать два варианта:
12/1import re
regex = r"(?:^|([/+ #_;.-]))(?:\d{1,8})(?!\d)"
test_str = ("12\n"
"123456789\n"
"1234567890\n"
"123456789/1234567890\n"
"123456789/1/123456789\n"
"123456789+1234567890")
def subst(match):
m = match.group(1)
return "" if m else "NaN"
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)
if result:
print(result)
Выход:
NaN
123456789
1234567890
123456789/1234567890
123456789/123456789
123456789+1234567890
df["Orders"].str.findall(r'[/+ #_;.-]?\b[0-9]{9,10}\b').str.join('')помогает?