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

Как написать регулярное выражение, которое исключает, а не совпадение, например, not (this | string)?

Я с трудом пытаюсь создать регулярное выражение Emacs, которое исключает группы. [^] исключает отдельные символы в наборе, но я хочу исключить определенные последовательности символов: что-то вроде [^(not|this)], так что строки, содержащие "not" или "this", не совпадают.

В принципе, я мог бы написать ([^n][^o][^t]|[^...]), но есть ли другой способ, что очиститель?

4b9b3361

Ответ 1

Прежде всего: [^n][^o][^t] не является решением. Это также исключает такие слова, как nil ([^n] не соответствует), bob ([^o] не соответствует) или cat ([^t] не соответствует).

Но можно создать регулярное выражение с базовым синтаксисом, который соответствует строкам, которые не содержат not и this:

^([^nt]|n($|[^o]|o($|[^t]))|t($|[^h]|h($|[^i]|i($|[^s]))))*$

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

Ответ 2

Это невозможно. Регулярные выражения предназначены для соответствия вещам, и это все, что они могут сделать.

Во-первых: [^] не обозначает "исключает группу", он обозначает отрицательный класс символов. Классы символов не поддерживают группировку в любой форме или форме. Они поддерживают одиночные символы (и, для удобства, диапазоны символов). Ваша попытка [^(not|this)] соответствует 100% эквиваленту [^)(|hinots], что касается двигателя регулярных выражений.

Из этой ситуации могут вывести три способа:

  • сопоставить (not|this) и исключить любые совпадения с помощью среды, в которой вы находитесь (отрицать результаты сопоставления)
  • используйте отрицательный внешний вид, если поддерживается вашим механизмом регулярных выражений и возможно в ситуации
  • переписать выражение, чтобы оно могло соответствовать: см. аналогичный вопрос, который я задал ранее

Ответ 3

Трудно поверить, что принятый ответ (от Gumbo) был фактически принят! Если бы это не было принято, потому что оно указывало, что вы не можете делать то, что хотите. Если у вас нет функции, которая генерирует такие регулярные выражения (как показывает Gumbo), составление их будет настоящей болью.

Каков реальный прецедент - что вы действительно пытаетесь сделать?

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

Ответ заключается в том, чтобы использовать регулярное выражение для соответствия тому, что вы не хотите, а затем вычесть из исходного домена. IOW, не пытайтесь сделать regexp делать исключение (оно не может); выполните исключение после использования регулярного выражения в соответствии с тем, что вы хотите исключить.

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

Ответ 4

Попробуйте флеш-линии M-x.

Ответ 5

Похоже, вы пытаетесь сделать негативный взгляд. т.е. вы пытаетесь остановить совпадение, как только вы достигнете некоторого разделителя.

Emacs не поддерживает lookahead напрямую, но поддерживает не-жадную версию *, + и? операторы (*?, +?,?), которые могут использоваться в той же цели в большинстве случаев.

Так, например, чтобы совместить тело этой функции javascript:

bar = function (args) {
    if (blah) {
        foo();
    }
};

Вы можете использовать это регулярное выражение emacs:

function ([^)]+) {[[:ascii:]]+?};

Здесь мы останавливаемся, когда находим две последовательности элементов "};". [[: ascii:]] используется instad "." потому что он работает на нескольких строках.

Это немного отличается от негативного взгляда, потому что}; сама последовательность соответствует, однако, если ваша цель состоит в том, чтобы извлечь все до этой точки, вы просто используете группу захвата\(и \).

См. руководство emges regex: http://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html

В качестве побочного примечания, если вы пишете какое-либо регулярное выражение emacs, обязательно запустите M-x re-builder, который выведет небольшую среду IDE для записи вашего регулярного выражения в текущий буфер.

Ответ 6

В случае использования строки для логического теста я делаю следующее:

;; Code to match string ends with '-region' but excludes those that has 'mouse'.
M-x ielm RET
*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (setq str1 "mouse-drag-region" str2 "mou-drag-region" str3 "mou-region-drag")
"mou-region-drag"
ELISP> (and (string-match-p "-region$" str1) (not (string-match-p "mouse" str1)))
nil
ELISP> (and (string-match-p "-region$" str2) (not (string-match-p "mouse" str2))) 
t
ELISP> (and (string-match-p "-region$" str3) (not (string-match-p "mouse" str3)))
nil

Я использую этот подход, чтобы избежать ошибки функции, которую я обсуждал Здесь::