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

Как использовать встроенные модификаторы в С# regex?

Как использовать встроенные модификаторы вместо RegexOptions.Option?

Например:

Regex MyRegex = new Regex(@"[a-z]+", RegexOptions.IgnoreCase);

Как мне переписать это с помощью встроенного символа i?

http://msdn.microsoft.com/en-us/library/yd1hzczs.aspx

4b9b3361

Ответ 1

Вы можете использовать встроенные модификаторы следующим образом:

// case insensitive match
Regex MyRegex = new Regex(@"(?i)[a-z]+");  // case insensitive match

или, инвертируйте значение модификатора, добавив знак минуса:

// case sensitive match
Regex MyRegex = new Regex(@"(?-i)[a-z]+");  // case sensitive match

или, включите и выключите их:

// case sensitive, then case-insensitive match
Regex MyRegex = new Regex(@"(?-i)[a-z]+(?i)[k-n]+");

В качестве альтернативы вы можете использовать синтаксис диапазона модификатора режима, используя двоеточие : и скобку группировки, которая привязывает модификатор только к этой группе:

// case sensitive, then case-insensitive match
Regex MyRegex = new Regex(@"(?-i:[a-z]+)(?i:[k-n]+)");

Вы можете использовать несколько модификаторов за один раз, например, (?is-m:text), или за другим, если вы обнаружите, что яснее (?i)(?s)(?-m)text (я этого не делаю). Если вы используете синтаксис включения/выключения, помните, что модификатор работает до следующего переключателя или конца регулярного выражения. И наоборот, с использованием измененных по мосту интервалов после диапазона будет применяться поведение по умолчанию.

Наконец: разрешенные модификаторы в .NET(используйте минус для инвертирования режима):

x разрешить пробелы и комментарии
s однострочный режим
m многострочный режим
i нечувствительность к регистру
n допускает только явный захват (специфичный для .NET)

Ответ 2

Используйте его следующим образом:

Regex MyRegex = new Regex(@"(?i:[a-z]+)");

Префикс встроенной опции для вашего шаблона с помощью (?<option>:<pattern>). В этом случае опция "i" для IgnoreCase.

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

@"(?i)[a-z]+"

Также возможно использовать несколько опций и включать и выключать их:

// On: IgnoreCase, ExplicitCapture. Off: IgnorePatternWhitespace
@"(?in-x)[a-z]+"

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

Вот несколько подробный пример. Я рекомендую вам поиграть с ним, чтобы понять, когда варианты вступают в силу.

string input = "H2O (water) is named Dihydrogen Monoxide or Hydrogen Hydroxide. The H represents a hydrogen atom, and O is an Oxide atom.";

// n = explicit captures
// x = ignore pattern whitespace
// -i = remove ignorecase option
string pattern = @"di?(?nx-i) ( hydrogen ) | oxide";
var matches = Regex.Matches(input, pattern, RegexOptions.IgnoreCase);
Console.WriteLine("Total Matches: " + matches.Count);
foreach (Match match in matches)
{
    Console.WriteLine("Match: {0} - Groups: {1}", match.Value, match.Groups[1].Captures.Count);
}

Console.WriteLine();

// n = explicit captures
// x = ignore pattern whitespace
// -i = remove ignorecase option
// -x = remove ignore pattern whitespace
pattern = @"di?(?nx-i) (?<H> hydrogen ) (?-x)|oxide";
matches = Regex.Matches(input, pattern, RegexOptions.IgnoreCase);
Console.WriteLine("Total Matches: " + matches.Count);
foreach (Match match in matches)
{
    Console.WriteLine("Match: {0} - Groups: {1}", match.Value, match.Groups["H"].Captures.Count);
}

Выход для выше:

Total Matches: 3
Match: Dihydrogen - Groups: 0
Match: oxide - Groups: 0
Match: oxide - Groups: 0

Total Matches: 3
Match: Dihydrogen - Groups: 1
Match: oxide - Groups: 0
Match: oxide - Groups: 0

В обоих шаблонах используется RegexOptions.IgnoreCase, что позволяет "ди" быть нечувствительным к регистру и, таким образом, соответствовать "Дигидроген" (капитал D). Поскольку явный захват включен, первый пример не имеет групп для ( hydrogen ), поскольку он не использует именованную группу, что является требованием для явного захвата. Второй шаблон имеет 1 группу, поскольку использует (?<H> hydrogen ).

Затем обратите внимание, что второй шаблон изменен, чтобы использовать (?-x)|oxide в конце. Поскольку IgnorePatternWhitespace отключен после захвата водорода, оставшаяся часть шаблона должна быть правильно сформирована из-за отсутствия дополнительных пробелов (сравните с первым рисунком), пока (?x) не включится позже в шаблоне. Это не имеет никакой реальной цели, а просто показывает глубокое использование встроенных опций, чтобы продемонстрировать, когда они действительно нажимают.