Regex: строка соответствия, если она содержит слово [дубликат]

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

Обещания отлично подходят для:

Мониторинг синхронных операций. Необходимо уведомлять только один раз (обычно это завершение или ошибка). Координация или управление несколькими асинхронными операциями, такими как последовательность или ветвление асинхронных операций или одновременное управление несколькими операциями в полете. Распространение ошибок из вложенных или глубоко вложенных асинхронных Операции Получение кода для использования async / await (или использования его сейчас с транспилером) Операции, которые соответствуют модели Promise, где есть только три состояния: pending, fulfilled и rejected и где состояние переходит из pending => fulfilled или из pending => rejected могут не меняться (один односторонний переход). Динамическое связывание или цепочка асинхронных операций (например, выполнение этих двух операций async, проверка результата, а затем принятие решения о том, какие другие операции асинхронного действия выполняются на основе промежуточного результата). Управление комбинацией асинхронных и синхронных операций. Автоматическое обнаружение и распространение любых исключений, которые происходят в асинхронных завершающих обратных вызовах (в простых обратных вызовах эти исключения иногда скрытно скрыты).

Обещания отлично подходят для:

Контроль синхронных операций Уведомления, которые могут возникать более одного раза (и, следовательно, необходимо вызвать обратный вызов более одного раза). Обещания - это одноразовые устройства и не могут использоваться для повторных уведомлений. Это нужно уведомить только один раз (обычно это завершение или ошибка)

И я также добавлю EventEmitter в микс.

EventEmitters отлично для:

Уведомления, которые могут возникать более одного раза (и, следовательно, необходимо вызвать обратный вызов более одного раза). Обезьяны являются одноразовыми устройствами и не могут использоваться для повторных уведомлений. Интерфейс с моделью событий, особенно когда события могут происходить более одного раза (например, потоки) Координация или управление несколькими асинхронными операциями, такими как последовательность или ветвящиеся асинхронные операции или одновременное управление несколькими операциями в полете

EventEmitters отлично подходят для:

Если ваши обратные вызовы соответствуют соглашению о вызове узла с обратным вызовом, переданным в качестве последнего аргумента и называемым как callback(err, result), то вы несколько автоматически обертываете родительскую функцию обещанием с помощью util.promisify() в node.js или используете библиотеку обещаний Bluebird , с Promise.promisify().

С помощью Bluebird вы можете даже обещать весь модуль (который использует асинхронные обратные вызовы в узле вызова node.js) сразу, например:

const Promise = require('bluebird'); const fs = Promise.promisifyAll(require('fs')); fs.writeFileAsync("file.txt", data).then(() => { // done here }).catch(err => { // error here });

В node.js версии 8 +

Теперь есть util.promisify(), который преобразует асинхронную функцию, которая использует асинхронный вызов node.js

Пример из Библиотека обещаний Bluebird

const util = require('util'); const fs = require('fs'); const stat = util.promisify(fs.stat); // usage of promisified function stat('.').then((stats) => { // Do something with `stats` }).catch((error) => { // Handle the error. });

474
задан robsch 5 January 2016 в 17:25
поделиться

10 ответов

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

^(?!.*bar).*$
523
ответ дан Chris Van Opstal 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться

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

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

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

5
ответ дан Greg Bell 21 August 2018 в 16:43
поделиться

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

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

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

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

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

33
ответ дан Gumbo 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться
  • 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 21 August 2018 в 16:43
поделиться

Решение:

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

xxxxxx OK

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

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

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

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

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