Во-первых, вы почти никогда не хотите писать код, представляющий собой сочетание обратных вызовов и обещаний для асинхронных операций. Если вы переходите к обещаниям или представляете некоторые обещания, то вы, вероятно, захотите реорганизовать обратные вызовы в том же разделе кода в обещания. Для соответствующих типов операций существует много преимуществ обещаний по сравнению с обычными обратными вызовами, которые стоит усилий для преобразования, когда они уже работают в области кода.
Обещания отлично подходят для:
Мониторинг синхронных операций. Необходимо уведомлять только один раз (обычно это завершение или ошибка). Координация или управление несколькими асинхронными операциями, такими как последовательность или ветвление асинхронных операций или одновременное управление несколькими операциями в полете. Распространение ошибок из вложенных или глубоко вложенных асинхронных Операции Получение кода для использования 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.
});
Отличный способ сделать это - использовать отрицательный 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