Разделить заданную строку с помощью регулярных выражений - PullRequest
2 голосов
/ 01 апреля 2019

Попытка разбить строку на 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

Ответы [ 2 ]

5 голосов
/ 01 апреля 2019

Не уверен, что лучше, но вы можете использовать partition или 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("/")

Доку:


Полный пример:

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 голос
/ 01 апреля 2019

В этом ответе используется 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']]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...