Оператор else:
выполняется тогда и только тогда, когда цикл while больше не соответствует его условию (в вашем примере, когда n != 0
является ложным).
Таким образом, выход будет следующим:
5
4
3
2
1
what the...
Отличный способ сделать это - использовать отрицательный lookahead :
^(?!.*bar).*$
Следующее regex будет делать то, что вы хотите (до тех пор, пока поддерживаются отрицательные lookbehinds и lookaheads), правильное соответствие вещей; единственная проблема заключается в том, что она соответствует отдельным символам (т. е. каждое совпадение - это один символ, а не все символы между двумя последовательными «барами»), что может привести к высоким накладным расходам, если вы работаете с очень длинными строками.
b(?!ar)|(?<!b)a|a(?!r)|(?<!ba)r|[^bar]
/(?:(?!bar).)*/g
на foobar
возвращает foo
AND ar
.
– Krzysiek
7 January 2015 в 17:08
Я наткнулся на этот форум, пытаясь идентифицировать регулярное выражение для следующего английского оператора:
Учитывая входную строку, сопоставьте все , если эта строка ввода точно «бар»; например, я хочу сопоставить «барьер» и «disbar», а также «foo».
blockquote>Вот регулярное выражение, которое я придумал с помощью
^(bar.+|(?!bar).*)$
My English перевод регулярного выражения «соответствует строке, если она начинается с« bar »и имеет хотя бы один другой символ, или если строка не начинается с« bar ».
^(?!bar$).*
совпадает с этим (все, кроме точно bar
) и избегает повторения.
– bkDJ
6 June 2018 в 13:17
Если производительность не вызывает особой озабоченности, часто проще просто выполнить свои результаты через второй проход, пропуская те, которые соответствуют словам, которые вы хотите скрыть.
Регулярные выражения обычно означают, что вы все равно выполняете скрипты или какую-то низкопроизводительную задачу, поэтому находите решение, которое легко читать, легко понять и легко поддерживать.
У меня был список имен файлов, и я хотел исключить некоторые из них с таким поведением (Ruby):
files = [
'mydir/states.rb', # don't match these
'countries.rb',
'mydir/states_bkp.rb', # match these
'mydir/city_states.rb'
]
excluded = ['states', 'countries']
# set my_rgx here
result = WankyAPI.filter(files, my_rgx) # I didn't write WankyAPI...
assert result == ['mydir/city_states.rb', 'mydir/states_bkp.rb']
Вот мое решение:
excluded_rgx = excluded.map{|e| e+'\.'}.join('|')
my_rgx = /(^|\/)((?!#{excluded_rgx})[^\.\/]*)\.rb$/
Мои предположения для этого приложения:
.rb
. .
перед .rb
. Принятый ответ хорош, но на самом деле является обходным процессом из-за отсутствия простого оператора отрицательного выражения выражения в выражениях. Вот почему grep --invert-match
выходит. Таким образом, в * nixes вы можете выполнить желаемый результат с помощью труб и второго регулярного выражения.
grep 'something I want' | grep --invert-match 'but not these ones'
Все еще обходное решение, но, возможно, легче запомнить.
Вы можете либо использовать отрицательный внешний вид , либо смотреть назад :
^(?!.*?bar).*
^(.(?<!bar))*?$
Или использовать только основы:
^(?:[^b]+|b(?:$|[^a]|a(?:$|[^r])))*$
Эти все соответствуют всем, что не содержит bar
.
Просто подумал о чем-то другом, что можно было бы сделать. Это очень отличается от моего первого ответа, поскольку он не использует регулярные выражения, поэтому я решил сделать второй ответ.
Используйте эквивалентный метод вашего языка выбора split()
в строке со словом отрицать как аргумент о том, на что разделить. Пример с использованием Python:
>>> text = 'barbarasdbarbar 1234egb ar bar32 sdfbaraadf'
>>> text.split('bar')
['', '', 'asd', '', ' 1234egb ar ', '32 sdf', 'aadf']
Приятно, как это сделать, по крайней мере, на Python (я не помню, была ли функциональность такой же, как, например, Visual Basic или Java) , заключается в том, что он позволяет вам опознать, когда «строка» повторялась в строке из-за того, что пустые строки между «барами» включаются в список результатов (хотя пустая строка в начале происходит из-за того, что существует «бар» в начале строки). Если вы этого не хотите, вы можете просто удалить пустые строки из списка.
Надеюсь дополнить ответ
Как уточнил Крис Regex Tutorial - лучший ресурс для изучения регулярного выражения.
Однако он действительно потреблял время читать.
Я делаю чит-коды для удобства мнемоники. []
, ()
, {}
, ведущие к каждому классу, который легко вспомнить.
Regex =
{'single_character': ['[]', '.', {'negate':'^'}],
'capturing_group' : ['()', '|', '\\', 'backreferences and named group'],
'repetition' : ['{}', '*', '+', '?', 'greedy v.s. lazy'],
'anchor' : ['^', '\b', '$'],
'non_printable' : ['\n', '\t', '\r', '\f', '\v'],
'shorthand' : ['\d', '\w', '\s'],
}
Решение:
^(?!.*STRING1|.*STRING2|.*STRING3).*$
xxxxxx OK
xxxSTRING1xxx KO (желательно ли это)
xxxSTRING2xxx KO (желательно ли это)
xxxSTRING3xxx KO (желательно ли это)
foo
будет соответствовать,bar
не будет, ноfoobar
илиbarfoo
тоже не будет! – Bruno Corrêa Zimmermann 30 June 2017 в 21:01