Исключить список строк в validation - regex [duplicate]

Оператор else: выполняется тогда и только тогда, когда цикл while больше не соответствует его условию (в вашем примере, когда n != 0 является ложным).

Таким образом, выход будет следующим:

5
4
3
2
1
what the...
474
задан robsch 5 January 2016 в 17:25
поделиться

10 ответов

Отличный способ сделать это - использовать отрицательный lookahead :

^(?!.*bar).*$
523
ответ дан Chris Van Opstal 19 August 2018 в 06:10
поделиться
  • 1
    Это говорит все (я, вероятно, начал бы с (?! Bar) и застроил). Я не понимаю, почему другие люди делают это настолько сложным. – Beta 7 August 2009 в 15:49
  • 2
    К сожалению, это не работает со всеми языками. – JAB 7 August 2009 в 19:01
  • 3
    символ начала линии в начале делает довольно хорошую работу. – dhblah 23 October 2012 в 09:39
  • 4
    Красиво сделано - соответствует строке с указанной строкой, а строке ничего не предшествует, а за строкой следует что-либо. Это по определению отсутствие строки! потому что, если он присутствует, ему всегда будет предшествовать что-то, даже если его привязка к линии ^ – Pete_ch 13 November 2014 в 16:35
  • 5
    К сожалению, это не работает с фактическими словами. foo будет соответствовать, bar не будет, но foobar или barfoo тоже не будет! – Bruno Corrêa Zimmermann 30 June 2017 в 21:01

Следующее regex будет делать то, что вы хотите (до тех пор, пока поддерживаются отрицательные lookbehinds и lookaheads), правильное соответствие вещей; единственная проблема заключается в том, что она соответствует отдельным символам (т. е. каждое совпадение - это один символ, а не все символы между двумя последовательными «барами»), что может привести к высоким накладным расходам, если вы работаете с очень длинными строками.

b(?!ar)|(?<!b)a|a(?!r)|(?<!ba)r|[^bar]
40
ответ дан 11 revs 19 August 2018 в 06:10
поделиться
  • 1
    Вместо тех нескольких обновлений, которые заставляют нас читать неправильные ответы, прежде чем приступать к вашему окончательному ответу, почему бы не переписать свой ответ как полный, но без каких-то запутанных плохих частей? Если кто-то действительно заботится об истории редактирования, они могут использовать встроенные функции этого сайта. – Bryan Oakley 19 June 2012 в 14:12
  • 2
    Прошло два с половиной года с тех пор, как я написал этот ответ, но уверен. – JAB 19 June 2012 в 15:39
  • 3
    проклятье, что болит, попробуйте это (? :( ?! bar).) * – Bob 7 October 2014 в 19:15
  • 4
    @Mary, Это не сработает, как ожидалось. Например, /(?:(?!bar).)*/g на foobar возвращает foo AND ar. – Krzysiek 7 January 2015 в 17:08

Я наткнулся на этот форум, пытаясь идентифицировать регулярное выражение для следующего английского оператора:

Учитывая входную строку, сопоставьте все , если эта строка ввода точно «бар»; например, я хочу сопоставить «барьер» и «disbar», а также «foo».

Вот регулярное выражение, которое я придумал с помощью

^(bar.+|(?!bar).*)$

My English перевод регулярного выражения «соответствует строке, если она начинается с« bar »и имеет хотя бы один другой символ, или если строка не начинается с« bar ».

23
ответ дан Alan Moore 19 August 2018 в 06:10
поделиться
  • 1
    @ReReqest - у вас будет гораздо больше шансов ответить на этот вопрос, если вы разместите его как отдельный вопрос. В этом случае вы можете указать ссылку на этот вопрос, если хотите. По существу вопроса - это выглядит нормально, но я не являюсь гуру regex – Bostone 11 September 2010 в 18:47
  • 2
    Это был тот, который я искал. Это действительно соответствует всем, кроме бара. – Gabriel Hautclocq 17 December 2015 в 21:34
  • 3
    ^(?!bar$).* совпадает с этим (все, кроме точно bar) и избегает повторения. – bkDJ 6 June 2018 в 13:17

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

Регулярные выражения обычно означают, что вы все равно выполняете скрипты или какую-то низкопроизводительную задачу, поэтому находите решение, которое легко читать, легко понять и легко поддерживать.

59
ответ дан Bryan Oakley 19 August 2018 в 06:10
поделиться
  • 1
    Существует множество ситуаций, когда вы не контролируете рабочий процесс: вы просто можете написать одно регулярное выражение, которое является фильтром. – Steve Bennett 22 March 2018 в 05:08

У меня был список имен файлов, и я хотел исключить некоторые из них с таким поведением (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.
1
ответ дан Chaim Leib Halbert 19 August 2018 в 06:10
поделиться

Принятый ответ хорош, но на самом деле является обходным процессом из-за отсутствия простого оператора отрицательного выражения выражения в выражениях. Вот почему grep --invert-match выходит. Таким образом, в * nixes вы можете выполнить желаемый результат с помощью труб и второго регулярного выражения.

grep 'something I want' | grep --invert-match 'but not these ones'

Все еще обходное решение, но, возможно, легче запомнить.

5
ответ дан Greg Bell 19 August 2018 в 06:10
поделиться

Вы можете либо использовать отрицательный внешний вид , либо смотреть назад :

^(?!.*?bar).*
^(.(?<!bar))*?$

Или использовать только основы:

^(?:[^b]+|b(?:$|[^a]|a(?:$|[^r])))*$

Эти все соответствуют всем, что не содержит bar.

33
ответ дан Gumbo 19 August 2018 в 06:10
поделиться
  • 1
    Какие языки не поддерживают (отрицательные) lookbehinds и / или (отрицательные) образы в регулярном выражении? – JAB 6 August 2009 в 18:29
  • 2
    Я думаю, что дело в том, что, глядя на ваш шаблон, совсем не ясно, что все, что вы делаете, - это отклонение слова «бар». – Bryan Oakley 6 August 2009 в 18:34
  • 3
    @Bryan: И, по сути, он не отвергает слово «бар». Он просто отклоняет & quot; b & quot; после чего следует «ar». – JAB 6 August 2009 в 19:05
  • 4
    Хорошая идея, но не поддерживается повсюду. Afaik Javascript поддерживает негативный внешний вид, но не смотрит. Я не знаю подробностей о других языках, но это может быть полезно: ru.wikipedia.org/wiki/Comparison_of_regular_expression_engines – mik01aj 8 July 2015 в 07:58
  • 5
    (?:[^b][^a][^r])* – Έρικ Κωνσταντόπουλος 19 April 2016 в 17:14

Просто подумал о чем-то другом, что можно было бы сделать. Это очень отличается от моего первого ответа, поскольку он не использует регулярные выражения, поэтому я решил сделать второй ответ.

Используйте эквивалентный метод вашего языка выбора split() в строке со словом отрицать как аргумент о том, на что разделить. Пример с использованием Python:

>>> text = 'barbarasdbarbar 1234egb ar bar32 sdfbaraadf'
>>> text.split('bar')
['', '', 'asd', '', ' 1234egb ar ', '32 sdf', 'aadf']

Приятно, как это сделать, по крайней мере, на Python (я не помню, была ли функциональность такой же, как, например, Visual Basic или Java) , заключается в том, что он позволяет вам опознать, когда «строка» повторялась в строке из-за того, что пустые строки между «барами» включаются в список результатов (хотя пустая строка в начале происходит из-за того, что существует «бар» в начале строки). Если вы этого не хотите, вы можете просто удалить пустые строки из списка.

1
ответ дан JAB 19 August 2018 в 06:10
поделиться
  • 1
    Вопрос конкретно задает вопрос о регулярном выражении ... – Ajk_P 22 June 2017 в 18:25
  • 2
    @Ajk_P да, но такие ответы могут помочь OP думать вне коробки, они могли бы быть зафиксированы на регулярных выражениях, не понимая, что их можно решить без них. – Petruza 21 July 2017 в 15:53

Надеюсь дополнить ответ

Как уточнил Крис 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'],
 }
2
ответ дан JawSaw 19 August 2018 в 06:10
поделиться

Решение:

^(?!.*STRING1|.*STRING2|.*STRING3).*$

xxxxxx OK

xxxSTRING1xxx KO (желательно ли это)

xxxSTRING2xxx KO (желательно ли это)

xxxSTRING3xxx KO (желательно ли это)

21
ответ дан sgrillon 19 August 2018 в 06:10
поделиться
  • 1
    спасибо, это дало мне дополнительную информацию, которая мне нужна для нескольких слов – RozzA 30 October 2016 в 19:37
Другие вопросы по тегам:

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