#python #regex
#python #регулярное выражение
Вопрос:
Пытаюсь разбить строку на 2 части.
#Need to get 'I1234' and 'I56/I78'
name1 = 'I1234/I56/I78'
#Need to get 'I1234 ' and 'I56/I78'
name2 = 'I1234 /I56/I78'
#Need to get 'I1234 ' and 'I56 /I78'
name3 = 'I1234 /I56 /I78'
#Need to get '1234 ' and 'I56 /I78 '
name4 = 'I1234 /I56 /I78 '
Я попробовал это, и это сработало:
pat_a = re.compile(r'(. )(/)(. )')
Is there a better way ?
result = re.findall(pat_a, name2[::-1])
Редактировать
Возможны более сложные строки, например:
I78_[0]/abcd_/efg_ /I1234/I56
Комментарии:
1. Есть ли причина для отрицательного голосования?
2. Я не голосовал против, но, возможно, потому, что ваше описание не слишком четкое. «Пытаюсь разбить строку на 2 части». это мало что говорит нам о том, где в строке вы пытаетесь разорвать, или о шаблоне, который вы пытаетесь установить.
3. Как правильно разделить для I78_ [0]/abcd_ / efg_ /I1234 / I56 ?
4. @Dragonfly какой требуется вывод для более сложной строки? У меня было это в моем ответе — [‘ I78_[0]’, ‘abcd_ / efg_ / I1234 / I56’] — но правильно ли это?
Ответ №1:
Не уверен, что это лучше, но вы можете использовать partition
or split
с значением maxsplit=1, чтобы избежать re
импорта модуля:
print('I1234/I56/I78'.partition("/")) # ('I1234', '/', 'I56/I78')
print('I1234/I56/I78'.split("/",1)) # ['I1234', 'I56/I78']
Для partition
вам нужно было бы посмотреть на 0-й и 2-й индексы кортежа:
first, _ , last = 'I1234/I56/I78'.partition("/")
Doku:
- https://docs.python.org/3/library/stdtypes.html#str.partition
- https://docs.python.org/3/library/stdtypes.html#str.split
Полный пример:
name1 = 'I1234/I56/I78'
name2 = 'I1234 /I56/I78'
name3 = 'I1234 /I56 /I78'
name4 = 'I1234 /I56 /I78 '
for n in [name1,name2,name3,name4]:
print(n.partition("/")) # ('I1234', '/', 'I56/I78')
print(n.split("/",1)) # ['I1234', 'I56/I78']
Вывод (обратные косые черты экранированы — вот почему они удваиваются):
('I1234', '/', 'I56/I78') # using partition
['I1234', 'I56/I78'] # using split
('\I1234 ', '/', 'I56/I78') # partition
['\I1234 ', 'I56/I78'] # split .. etc.
('\I1234 ', '/', '\I56 /I78')
['\I1234 ', '\I56 /I78']
('\I1234 ', '/', '\I56 /\I78 ')
['\I1234 ', '\I56 /\I78 ']
Комментарии:
1. Спасибо, Патрик, у меня есть еще несколько примеров. Я отредактировал свой вопрос.
2. Я дал вам преимущество, но я бы предложил разделить ваши два решения и показать их отдельно. Кроме того, я бы взял 1-й и 3-й компоненты результата ‘partition’ и распечатал их, чтобы вы показали, как получить желаемый результат в каждом случае. Как бы то ни было, ваш ответ немного сбивает с толку. — Мне нравится, что вы показываете две альтернативы.
3. @Steve — вот почему я разделил решения сверху , а также показал, как top разделил их с помощью декомпозиции. Спасибо за отзыв
4. @PatrickArtner — да, ничего особенного. Я просто думаю, что было бы понятнее иметь возможность просматривать как код, так и выходные данные в виде двух уникальных примеров.
5. Спасибо. Это решение работает для первых 4 строк, но не для более сложной строки.
Ответ №2:
В этом ответе используется string.split
, который, по-видимому, является самым чистым методом по сравнению с регулярным выражением. Я рассматривал использование string.partition
, но оно выдает tuple
, что требует разделения индекса. Кроме того, выходные данные, связанные с string.partition
, не выдают запрошенный вами вывод.
В этом первом примере берется одна строка и выводится пара строк на основе вашего запроса на разделение.
# Need to get 'I1234 ' and 'I56 /I78'
name3 = 'I1234 /I56 /I78'
# The input name (name3) can be change in a for loop linked to your input.
split_input = name3.split('/', 1) # maxsplit=1
print (split_input)
# outputs
#####################################################################
# NOTE: the escaped backslashes, which doesn't match your requirement.
#####################################################################
['\I1234 ', '\I56 /I78']
В исходном выводе выше были созданы экранированные обратные косые черты, поэтому этот код удаляет их.
# Need to get 'I1234 ' and 'I56 /I78'
name3 = 'I1234 /I56 /I78'
# The input name (name3) can be change in a for loop linked to your input.
split_input = str(name3.split('/', 1)).encode('utf-8').decode('unicode_escape')
print (split_input)
# outputs
['I1234 ', 'I56 /I78'] # Do you need that trailing space?
Я не уверен, откуда изначально берутся ваши входные значения (например, файл, веб-сайт и т.д.), Поэтому я добавил значения из вашего вопроса в список для более быстрого тестирования. В следующем примере используются понимание списка и string.split.
my_strings = ['I1234/I56/I78', 'I1234 /I56/I78', 'I1234 /I56 /I78', 'I1234 /I56 /I78', 'I78_[0]/abcd_/efg_ /I1234/I56']
# Uses list comprehension and string.split to split the elements in your strings
split_input = [x.split('/', 1) for x in my_strings]
# The original output created escaped backslashes, so this code removes them.
decode_output = (str(split_input).encode('utf-8').decode('unicode_escape'))
print (decode_output)
# outputs
[['I1234', 'I56/I78'], ['I1234 ', 'I56/I78'], ['I1234 ', 'I56 /I78'], ['I1234 ', 'I56 /I78'], ['I78_[0]', 'abcd_/efg_ /I1234/I56']]
Комментарии:
1. Почему вы начинаете с совершенно другого ввода? Вместо строк вы используете списки списков строк, которые уже разделены. Также зачем эти махинации с экранированными обратными косыми чертами и разделением
str()
представления для вашегоsplit_input
? Это ответ на совершенно другой вопрос…2. Просмотрев мой ответ, я отметил, что опубликовал выходные данные кода в качестве входных значений. Я исправил эту ошибку. Спасибо, что указали на ошибку.
3. Я добавил входные значения в вопросе OP в список, чтобы я мог обрабатывать их быстрее. Я также сделал это, потому что я не знаю, откуда будут поступать входные значения и как OP должен их выводить, помимо их печати. Я обновил свой ответ, чтобы использовать входные данные OP точно так, как это было предоставлено.