Как использовать встроенные модификаторы вместо RegexOptions.Option
?
Например:
Regex MyRegex = new Regex(@"[a-z]+", RegexOptions.IgnoreCase);
Как мне переписать это с помощью встроенного символа i
?
Как использовать встроенные модификаторы вместо RegexOptions.Option
?
Например:
Regex MyRegex = new Regex(@"[a-z]+", RegexOptions.IgnoreCase);
Как мне переписать это с помощью встроенного символа i
?
Вы можете использовать встроенные модификаторы следующим образом:
// 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)
Используйте его следующим образом:
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)
не включится позже в шаблоне. Это не имеет никакой реальной цели, а просто показывает глубокое использование встроенных опций, чтобы продемонстрировать, когда они действительно нажимают.