Исключить символы из класса символов

Есть ли простой способ сопоставить все символы в классе, кроме определенного набора из них? Например, если в lanaguage, где я могу использовать \w для соответствия набору всех символов в Юникодном слове, существует ли способ просто исключить символ, подобный подчеркиванию "_" из этого совпадения?

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

^(\w&[^_])+$

Ответ 1

Это действительно зависит от вашего аромата регулярного выражения.

.NET

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

[\w-[_]]

Если за a - следует вложенный класс символов, он вычитается. Просто как это...

Java

... предоставляет гораздо более богатый набор функций набора символов символов. В частности, вы можете получить пересечение двух наборов типа [[abc]&&[cde]] (что в этом случае даст c). Пересечение и отрицание вместе вызывают вычитание:

[\w&&[^_]]

Все другие ароматы

... (которые поддерживают lookaheads) позволяют вам подражать вычитанию с помощью отрицательного вида:

(?!_)\w

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

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

Ответ 2

Вы можете использовать отрицание класса \w (- > \w) и исключить его:

^([^\W_]+)$

Ответ 3

Отрицательный взгляд - это правильный путь, насколько я понимаю ваш вопрос:

^((?!_)\w)+$

Ответ 4

Попробуйте использовать вычитание:

[\w&&[^_]]+

Примечание. Это будет работать на Java, но может не работать в каком-либо другом двигателе Regex.

Ответ 5

Это можно сделать в python с regex module. Что-то вроде:

import regex as re
pattern = re.compile(r'[\W_--[ ]]+')
cleanString = pattern.sub('', rawString)

Обычно вы устанавливаете модуль regex с pip:

pip install regex

ИЗМЕНИТЬ

Модуль регулярных выражений имеет два варианта поведения: версия 0 и версия 1. Упорядочение (как указано выше) - это поведение версии 1. Требование pypi docs версии 1 является поведением по умолчанию, но вы можете обнаружить, что это не так. Вы можете проверить с помощью

import regex
if regex.DEFAULT_VERSION == regex.VERSION1:
  print("version 1")

Чтобы установить его на версию 1:

regex.DEFAULT_VERSION = regex.VERSION1

или использовать версию 1 в одном выражении:

pattern = re.compile(r'(?V1)[\W_--[ ]]+')