Python 2.7 - Regex - Как найти некоторые символы X в некоторых частях строки Y, которые находятся между двумя символами Z1 и Z2 внутри большой строки S? [Дубликат]

Вы неправильно понимаете, как работают булевы выражения; они не работают как английское предложение и предполагают, что вы говорите о том же сравнении для всех имен здесь. Вы ищете:

if x == 1 or y == 1 or z == 1:

x и y иначе оцениваются самостоятельно (False, если 0, True в противном случае).

Вы можете сократить это, используя тест сдерживания против кортежа :

if 1 in (x, y, z):

или еще лучше:

if 1 in {x, y, z}:

с помощью a set , чтобы воспользоваться тестом на членство в постоянной стоимости (in занимает фиксированное количество времени, независимо от того, какой левый операнд есть).

Когда вы используете or, питон видит каждая сторона оператора в виде отдельных выражений. Выражение x or y == 1 рассматривается как первый булевой тест для x, тогда, если это False, проверяется выражение y == 1.

Это связано с приоритетом оператора . Оператор or имеет более низкий приоритет, чем тест ==, поэтому последний сначала оценивается .

Однако, даже если это были не случай, а выражение x or y or z == 1 было фактически интерпретировано как (x or y or z) == 1, но это все равно не будет делать то, что вы ожидаете от него.

x or y or z будет оценивать первый аргумент, который является «правдивым», например. не False, числовое 0 или пустое (см. логические выражения для получения подробной информации о том, что Python считает ложным в булевом контексте).

Итак, для значений x = 2; y = 1; z = 0, x or y or z будет разрешено 2, потому что это первое истинное значение в аргументах. Тогда 2 == 1 будет False, хотя y == 1 будет True.

То же самое относится к обратному; тестирование нескольких значений по одной переменной; x == 1 or 2 or 3 потерпит неудачу по тем же причинам. Используйте x == 1 or x == 2 or x == 3 или x in {1, 2, 3}.

0
задан mazouu rahim 4 December 2015 в 13:31
поделиться

3 ответа

Вы можете заменить неживое подстановочное соответствие для символов в круглых скобках с помощью функции, которая разделяет совпадение по пробелам и присоединяется к ней.

>>> import re
>>> res = '(321, 3)-(m-5, 5) -(31,1)'
>>> re.sub(r'\(.*?\)', lambda x: ''.join(x.group(0).split()), res)
'(321,3)-(m-5,5) -(31,1)'
1
ответ дан TigerhawkT3 27 August 2018 в 11:35
поделиться

Вы можете преобразовать строку в список, пройти каждую букву и подсчитать, если вы находитесь в скобках или нет. В ToRemove вы собираете позиции пробелов, которые затем удаляете из списка. Затем вы конвертируете список обратно в строку ...

res = '(321, 3)-(m-5, 5) -(31,1)'
r = list(res)
insideBracket = 0
toRemove = []
for pos,letter in enumerate(r):
    if letter == '(':
        insideBracket += 1
    elif letter == ')':
        insideBracket -= 1
    if insideBracket > 0:
        if letter == ' ':
            toRemove.append(pos)

for t in toRemove[::-1]:
    r.pop(t)

result = ''.join(r)
print(result)
0
ответ дан elzell 27 August 2018 в 11:35
поделиться

Я думаю, что регулярные выражения недостаточно мощны, чтобы делать то, что вы хотите здесь; вы хотите удалить все пробелы, найденные между символами скобок. Проблема в том, что решение этого для общего случая означает, что вы выполняете контекстно-зависимое соответствие строки, а регулярные выражения в основном нечувствительны к контексту и поэтому не могут выполнять вашу работу. Есть lookaheads и lookbehinds , которые могут ограничивать совпадения с конкретными контекстами, но они не будут решать вашу проблему в общем случае:

Содержащийся шаблон должен соответствовать только строки некоторой фиксированной длины, что означает, что abc или a|b разрешены, но a* и a{3,4} - нет. Ссылки группы не поддерживаются, даже если они соответствуют строкам некоторой фиксированной длины.

Из-за этого я сначала сопоставлял бы группы скобок:

>>> re.split(r'(\([^)]*\))', res)
['', '(321, 3)', '-', '(m-5, 5)', ' -', '(31,1)', '']

, а затем удалите пробелы из них на втором шаге перед тем, как join все вернется в одну строку:

>>> g = re.split(r'(\([^)]*\))', res)
>>> g[1::2] = [re.sub(r'\s*', '', x) for x in g[1::2]]
>>> ''.join(g)
'(321,3)-(m-5,5) -(31,1)'
0
ответ дан wildwilhelm 27 August 2018 в 11:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: