Я хочу проверить, содержит ли строка одинаковое количество скобок, например, допустим, у меня есть такая строка
Привет {{имя}} как дела?
поэтому я хочу проверить, равны ли фигурные скобки вокруг имени или нет.
Я пробовал реализацию стека, но это работает хорошо, только если строка содержит только скобки, а не какой-либо другой символ.
Если в строке могут появляться только фигурные скобки:
def check(s, left='{', right='}'):
b = 0
for c in s:
if c == left:
b += 1
if c == right:
if b == 0:
return False
b -= 1
return b == 0
Это упрощенная версия реализации стека. Если у вас есть другие виды скобок, которые вы хотите проверить, вам понадобится реальный стек и просто пропустите символы без скобок в ваших проверках.
Евгений Кузьмович спасибо, что если я хочу проверить точное количество скобок, например, если есть 2 открывающих и 2 закрывающих скобки, то это только считается действительным
Подумайте, что представляет собой b
в этой реализации. Вы можете добавить некоторые проверки во время итераций. Например, если b>2
что-то не так (т.е. "{{{hello}}}"
). Если b==1 and c != left
что-то не так (т.е. "{a{hello}}"
). И т. д.
Евгений Кузьмович, что я могу понять, и это работает, но это не сработало, если строка имеет более одной переменной, например привет {{имя}} {{второе_имя}} и т. д.
Автор @Evhen Kusmovych работает, но я хочу поделиться еще одной попыткой решить эту проблему. Я хочу показать попытку с регулярным выражением и рекурсией:
import re
def compare_brackets(left, right, test_str, matches):
regex = r"{}[a-zA-Z0-9\s]*{}".format(left, right)
match = re.search(regex, test_str, re.MULTILINE)
if match:
test_str = test_str[:match.start()] + 'a' + test_str[match.end():]
matches.append(match.group())
_, test_str = compare_brackets(left, right, test_str, matches)
return len(matches), test_str
def bad_brackets(left, right, leftover_str, bad_matches):
regex = r"{}|{}".format(left, right)
bad_match = re.search(regex, leftover_str, re.MULTILINE)
if bad_match:
leftover_str = leftover_str[:bad_match.start()] + 'a' + leftover_str[bad_match.end():]
bad_matches.append(bad_match.group())
bad_brackets(left, right, leftover_str, bad_matches)
return len(bad_matches), leftover_str
Я реализовал две функции, которые рекурсивно вызывают себя, чтобы сначала найти все подходящие скобки, начиная с первого совпадения внутренних скобок, и удалить их из строки. После того, как все допустимые скобки удалены из строки, вторая функция использует оставшуюся строку и ищет недопустимые скобки.
Я тестировал три разные строки:
count_of_brackets, test_str = compare_brackets('{','}', "Hi {{name}} how are you", [])
count_of_bad_brackets, leftover = bad_brackets('{','}', test_str, [])
print('Found {} valid bracket pairs and {} broken brackets'.format(count_of_brackets, count_of_bad_brackets))
count_of_brackets, test_str = compare_brackets('{','}', "Hi {{{name}}} how are} you",[])
count_of_bad_brackets, leftover = bad_brackets('{','}', test_str, [])
print('Found {} valid bracket pairs and {} broken brackets'.format(count_of_brackets, count_of_bad_brackets))
count_of_brackets, test_str = compare_brackets('{','}', "Hi {{{my name}}} is your {{bodypart}} ok", [])
count_of_bad_brackets, leftover = bad_brackets('{','}', test_str, [])
print('Found {} valid bracket pairs and {} broken brackets'.format(count_of_brackets, count_of_bad_brackets))
выход
Found 2 valid bracket pairs and 0 broken brackets
Found 3 valid bracket pairs and 1 broken brackets
Found 5 valid bracket pairs and 0 broken brackets
Мое решение работает для нескольких пар скобок. Но регулярное выражение также полезно для этой задачи.
О да, я вижу твое изменение b -= 1
сейчас
пожалуйста, поделитесь реализацией стека