Я пытаюсь использовать встроенный метод pandas .str.extract для извлечения подстроки из столбца в импортированном мной фрейме данных. Все записи в столбце имеют следующую структуру:
x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018
Таким образом, по сути, это всегда число с плавающей запятой, за которым следует строка (которая не всегда имеет одинаковую длину слов), за которой следует трехбуквенный код, который является либо XYZ, либо ZYX, а затем дата.
Я пытаюсь извлечь Test1, Test2 и Test3 из приведенного выше примера, что означает, что я хочу убрать процент в начале, а там, где происходит XYZ | ZYX, я хочу, чтобы все было после того, как исчезло (включая трехбуквенный код).
Я все утро читал о регулярных выражениях, но я немного изо всех сил пытаюсь создать код с использованием экстракта панд, который может вытащить именно то, что я хочу. Какие-либо предложения? Дальнейшее, что я получил, - это нижеприведенное, где показаны только проценты в начале (я пытался разбить его на три категории):
.str.extract('(\d\.\d+%.)')






Вы можете использовать шаблон с опережением, чтобы определить, когда прекратить сопоставление.
([\w\s]+?)(?=\w{3}\|)'
Подробности
( # first capture group
[\w\s]+? # match letters or whitespaces
)
(?= # lookahead
\w{3} # fixed length 3 chars
\| # literal `|`
)
s = pd.Series(['x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018'])
s.str.extract(r'([\w\s]+?)(?=\w{3}\|)', expand=False)
0 Test1 Test2 Test3
dtype: object
Регулярное выражение, которое вы можете, могло бы быть следующим:
r"(\d\.\d+%.)(.*)\s([A-Z]{3})\s([A-Z]{1}[a-z]{2})\s([0-9]{4}$)"
где \d\.\d+%. соответствует проценту
[A-Z]{3} соответствует буквенному коду
[A-Z]{1}[a-z]{2} соответствует месяцу
[0-9]{4}$ соответствует году, в конце
.* соответствует остальным, следовательно, тестам.
\s соответствует одному пробелу, и это вне совпадений.
Итоговый код может быть примерно таким:
import re
string = "3.14% Test1 Test2 Test3 XYZ Oct 2018"
matches = re.findall(r"(\d\.\d+%.)(.*)\s([A-Z]{3})\s([A-Z]{1}[a-z]{2})\s([0-9]{4}$)", string)[0]
percentage = matches[0]
mytest = matches[1].split(' ')
letter_code = matches[2]
month = matches[3]
year = matches[4]
print(percentage) # 3.14%
print(mytest) # ['Test1', 'Test2', 'Test3']
print(letter_code) # XYZ
print(month) # Oct
print(year) # 2018
Вы можете попробовать Позитивный просмотр назад:
import re
pattern=r'(?<=%)(\s.+)?XYZ|ZYX'
text = """x.xx% Test1 Test2 Test3 XYZ|ZYX Oct 2018
x.xx% Test1 Test2 Test3 ZYX|XYZ Oct 2018"""
for i in re.findall(pattern,text):
data=re.sub(re.escape('ZYX|'),' ',i)
if data.split():
print(data.split())
выход:
['Test1', 'Test2', 'Test3']
['Test1', 'Test2', 'Test3']