регулярное выражение для соответствия двум словам, но исключить, если определенные символы между [duplicate]

COUNTER PRIMITIVE

Давайте определим функции обратного вызова следующим образом:

// ****************************
// COUNTER BEING A PRIMITIVE
// ****************************
function test1() {
    for (var i=0; i<2; i++) {
        setTimeout(function() {
            console.log(i);
        });
    }
}
test1();
// 2
// 2

По завершении таймаута он будет печатать 2 для обоих. Это связано с тем, что функция обратного вызова обращается к значению, основанному на лексической области , где была определена функция.

Чтобы передать и сохранить значение при определении обратного вызова, мы можем создать замыкание , чтобы сохранить значение до вызова обратного вызова. Это можно сделать следующим образом:

function test2() {
    function sendRequest(i) {
        setTimeout(function() {
            console.log(i);
        });
    }

    for (var i = 0; i < 2; i++) {
        sendRequest(i);
    }
}
test2();
// 1
// 2

Теперь в этом особенность: «Примитивы передаются по значению и копируются. Таким образом, когда ограничение определено, они сохраняют значение из предыдущего цикла».

COUNTER BEING OBJECT

Поскольку у закрытий есть доступ к родительским переменным функции через ссылку, этот подход будет отличаться от такового для примитивов.

// ****************************
// COUNTER BEING AN OBJECT
// ****************************
function test3() {
    var index = { i: 0 };
    for (index.i=0; index.i<2; index.i++) {
        setTimeout(function() {
            console.log('test3: ' + index.i);
        });
    }
}
test3();
// 2
// 2

Итак, даже если для переменной, передаваемой как объект, создается замыкание, значение индекса цикла не будет сохранено. Это означает, что значения объекта не копируются, а к ним обращаются через ссылку.

function test4() {
    var index = { i: 0 };
    function sendRequest(index, i) {
        setTimeout(function() {
            console.log('index: ' + index);
            console.log('i: ' + i);
            console.log(index[i]);
        });
    }

    for (index.i=0; index.i<2; index.i++) {
        sendRequest(index, index.i);
    }
}
test4();
// index: { i: 2}
// 0
// undefined

// index: { i: 2}
// 1
// undefined

12
задан Jorge Campos 15 May 2016 в 16:16
поделиться

4 ответа

Вам нужен сдержанный жадный токен :

abc(?:(?!abc|xyz|123).)*123(?:(?!abc|xyz).)*xyz

См. демонстрацию regex

Чтобы убедиться, что она соответствует через строки, используйте флаг re.DOTALL при компиляции регулярного выражения.

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

Сведения о шаблоне:

  • abc - соответствие abc
  • (?:(?!abc|xyz|123).)* - сопоставить любой символ, который не является отправной точкой для последовательностей символов abc, xyz или 123
  • 123 - буквальная строка 123
  • (?:(?!abc|xyz).)* - любой символ, который не является исходной точкой для последовательностей символов abc или xyz
  • xyz - конечная подстрока xyz

См. Диаграмму ниже (если используется re.S, . будет означать AnyChar):

См. Демонстрацию Python :

import re
p = re.compile(r'abc(?:(?!abc|xyz|123).)*123(?:(?!abc|xyz).)*xyz', re.DOTALL)
s = "abc 123 xyz\nabc abc 123 xyz\nabc text 123 xyz\nabc text xyz xyz"
print(p.findall(s))
// => ['abc 123 xyz', 'abc 123 xyz', 'abc text 123 xyz']
24
ответ дан Eric Leschinski 4 September 2018 в 07:34
поделиться

Комментарий на hvd вполне уместен, и это только пример. В SQL, например, я думаю, что было бы более ясным:

where val like 'abc%123%xyz' and
      val not like 'abc%abc%' and
      val not like '%xyz%xyz'

Я предполагаю, что что-то совершенно похожее сделать в других средах.

2
ответ дан Jonathan Leffler 4 September 2018 в 07:34
поделиться

Использование PCRE для решения будет:

Это использование флага m. Если вы хотите проверить только с начала и конца строки, добавьте ^ и $ в начало и конец соответственно

abc(?!.*(abc|xyz).*123).*123(?!.*(abc|xyz).*xyz).*xyz

Regular expression visualization [/g1]

Демоверсия Debuggex

2
ответ дан Jorge Campos 4 September 2018 в 07:34
поделиться

Вы можете использовать lookaround.

/^abc(?!.*abc).*123.*(?<!xyz.*)xyz$/g

(я его не тестировал.)

1
ответ дан Kenny Lau 4 September 2018 в 07:34
поделиться
Другие вопросы по тегам:

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