Подтвердить что ты не робот

В JavaScript, как я могу использовать регулярное выражение для соответствия, если слова не входят в список исключенных слов?

Как использовать регулярное выражение для соответствия любому слову (\ w), за исключением списка определенных слов? Например:

Я хочу совместить слова use и utilize и любые слова после него, кроме слов something или fish.

use this  <-- match
utilize that  <-- match
use something   <-- don't want to match this
utilize fish <-- don't want to match this

Как указать список слов, с которыми я не хочу сопоставлять?

4b9b3361

Ответ 1

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

(use|utilize)\s(?!fish|something)(\w+)

Это будет соответствовать "использовать" или "использовать", за которым следует пробел, а затем, если следующее слово не "рыба" или "что-то", оно будет соответствовать следующему слову.

Ответ 2

Это должно сделать это:

/(?:use|utilize)\s+(?!something|fish)\w+/

Ответ 3

Не жестко задавайте регулярные выражения

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

Затем вы можете инкапсулировать это тестирование в функцию, которая возвращает логическое значение, основанное на значениях времени выполнения ваших массивов. Например:

'use strict';

// Join arrays of terms with the alternation operator.
var searchTerms   = new RegExp(['use', 'utilize'].join('|'));
var excludedTerms = new RegExp(['fish', 'something'].join('|'));

// Return true if a string contains only valid search terms without any
// excluded terms.
var isValidStr = function (str) {
    return (searchTerms.test(str) && !excludedTerms.test(str));
};

isValidStr('use fish');       // false
isValidStr('utilize hammer'); // true

Ответ 4

Некоторые люди, столкнувшись с проблемой, думают: "Я знаю, я буду использовать регулярные выражения.

Теперь у них есть две проблемы.

Регулярные выражения подходят для соответствия регулярным последовательностям символов, а не слов. Любой лексер + парсер будет гораздо более подходящим. Например, грамматика для этой задачи будет выглядеть очень просто в Antlr. Если вы не можете позволить себе кривую обучения за лексерами/парсерами (они довольно легки для вашей заданной задачи), то разделение текста на слова с регулярным выражением, а затем простого поиска с опережением 1 будет достаточно.

Регулярные выражения со словами очень сложны очень быстро. Их трудно читать и трудно выполнять.

Обновление: Спасибо за все downvotes. Вот пример того, что я имел в виду.

import re

def Tokenize( text ):
    return re.findall( "\w+", text )

def ParseWhiteListedWordThenBlackListedWord( tokens, whiteList, blackList ):
    for i in range( 0, len( tokens ) - 1 ):
        if tokens[i] in whiteList and tokens[i + 1] not in blackList:
            yield ( tokens[i], tokens[i + 1] )

Вот несколько тестов производительности:

>>> timeit.timeit( 'oldtime()', 'from __main__ import oldtime', number=1 )
0.02636446265387349

>>> timeit.timeit( 'oldtime()', 'from __main__ import oldtime', number=1000 )
28.80968123656703

>>> timeit.timeit( 'newtime()', 'from __main__ import newtime', number=100 )
44.24506212427741

>>> timeit.timeit( 'newtime11()', 'from __main__ import newtime11', number=1 ) +
timeit.timeit( 'newtime13()', 'from __main__ import newtime13', number=1000 )
103.07938725936083

>>> timeit.timeit( 'newtime11()', 'from __main__ import newtime11', number=1 ) + 
timeit.timeit( 'newtime12()', 'from __main__ import newtime12', number=1000 )
0.3191265909927097

Некоторые примечания: тестирование было проведено над английским текстом "Pride anf Prejudice" Джейн Остин, первые слова были "Mr" и "my", вторыми словами были "Bennet" и "дорогие".

oldtime() является регулярным выражением. newtime() является Tokenizer + Parser, помните, что он выполнялся 100 раз, а не 1000, поэтому сопоставимое время для этого было бы ~ 442.

Следующие два теста предназначены для имитации повторных прогонов Parser над одним и тем же текстом, поскольку вы повторно используете результаты Tokenizer.

newtime11() - только токенизатор. newtime13() - это Parser с результатами, преобразованными в список (для имитации обхода результатов). newtime12() - это просто Parser.

Ну, регулярные выражения быстрее, довольно много в случае одного прохода, даже в случае генератора (основная часть времени тратится на токенизацию текста, в случае Tokenizer + Parser). Но выражения генератора чрезвычайно быстры, когда вы можете повторно использовать токенырованный текст и оценивать результаты парсера лениво.

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

Подход токенизатора + парсера имеет как преимущества, так и недостатки: - структура решения сложнее (больше элементов), но каждый элемент проще - элементы легко тестируются, включая автоматическое тестирование - он медленный, но он становится лучше, повторно используя один и тот же текст и оценивая результаты лениво - из-за генераторов и ленивой оценки, некоторые работы можно избежать - тривиально менять белый список и/или черный список - тривиально иметь несколько белых списков, несколько черных списков и/или их комбинации - тривиально добавлять новые парсеры, повторно использующие результаты токенизатора

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

Обновление: есть хорошее обсуждение regualr-выражений в лексинге и синтаксическом анализе на http://commandcenter.blogspot.ru/2011/08/regular-expressions-in-lexing-and.html, Я обобщу его с цитатой

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