#python #regex #nlp #data-cleaning
#python #регулярное выражение #nlp #очистка данных
Вопрос:
Я пытаюсь создать пользовательский токенизатор на python, который работает со встроенными тегами. Цель состоит в том, чтобы ввести строку следующим образом:
'This is *tag1* a test *tag2*.'
и пусть он выводит список, разделенный тегом и символом:
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', '*tag1*', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', '*tag2*', '.']
без тегов я бы просто использовал list()
, и я думаю, что нашел решение для работы с одним типом тега, но их несколько. Существуют также другие многосимвольные сегменты, такие как многоточия, которые должны быть закодированы как единый объект.
Одна вещь, которую я пробовал, — это замена тега одним неиспользуемым символом на регулярное выражение, а затем использование list()
в строке:
text = 'This is *tag1* a test *tag2*.'
tidx = re.match(r'*.*?*', text)
text = re.sub(r'*.*?*', r'#', text)
text = list(text)
затем я бы повторил его и заменил ‘#’ извлеченными тегами, но у меня есть несколько разных функций, которые я пытаюсь извлечь, и повторение процесса несколько раз с разными символами-заполнителями перед разделением строки кажется плохой практикой. Есть ли более простой способ сделать что-то подобное? Я все еще новичок в этом, поэтому есть еще много распространенных методов, о которых я не знаю. Я думаю, я также могу использовать более крупное регулярное выражение, которое охватывает все функции, которые я пытаюсь извлечь, но оно все равно кажется хакерским, и я бы предпочел использовать что-то более модульное, которое можно использовать для поиска других функций, не записывая каждый раз новое выражение.
Комментарии:
1. взгляните на лексические сканеры, напишите грамматику вашего текста, и он проанализирует ее для вас, или напишите свой собственный конечный автомат
Ответ №1:
Вы можете использовать следующее регулярное выражение с re.findall
:
*[^*]**|.
Смотрите демонстрацию регулярных выражений. Флаг re.S
or re.DOTALL
можно использовать с этим шаблоном, чтобы .
он также мог сопоставлять символы разрыва строки, которым он не соответствует по умолчанию.
Подробные сведения
*[^*]**
—*
символ, за которым следует ноль или более символов, отличных от*
, а затем*
|
— или.
— любой символ (сre.S
).
Смотрите демонстрацию Python:
import re
s = 'This is *tag1* a test *tag2*.'
print( re.findall(r'*[^*]**|.', s, re.S) )
# => ['T', 'h', 'i', 's', ' ', 'i', 's', ' ', '*tag1*', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', '*tag2*', '.']
Комментарии:
1. Кажется, это работает хорошо. Вместо того, чтобы расширять выражение для работы с эллипсами и другими функциями, я просто использовал еще пару функций регулярных выражений, чтобы преобразовать все это в теги по схеме звездочки, так что все должно работать нормально.
Ответ №2:
Я не уверен точно, что было бы лучше для вас, но вы должны иметь возможность использовать метод split() или метод .format(), представленный ниже, чтобы получить то, что вы хотите.
# you can use this to get what you need
txt = 'This is *tag1* a test *tag2*.'
x = txt.split("*") #Splits up at *
x = txt.split() #Splits all the words up at the spaces
print(x)
# also, you may be looking for something like this to format a string
mystring = 'This is {} a test {}.'.format('*tag1*', '*tag2*')
print(mystring)
# using split to get ['T', 'h', 'i', 's', ' ', 'i', 's', ' ', '*tag1*', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', '*tag2*', '.']
txt = 'This is *tag1* a test *tag2*.'
split = txt.split("*") #Splits up at *
finallist = [] # initialize the list
for string in split:
# print(string)
if string == '*tag1*':
finallist.append(string)
# pass
elif string == '*tag2*.':
finallist.append(string)
else:
for x in range(len(string)):
letter = string[x]
finallist.append(letter)
print(finallist)