Как использовать встроенные модификаторы в C # регулярных выражений? - PullRequest
17 голосов
/ 22 августа 2010

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

Например:

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

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

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

Ответы [ 2 ]

33 голосов
/ 22 августа 2010

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

// 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

, или включить их иoff:

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

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

// 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)

7 голосов
/ 22 августа 2010

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

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, который используетсяпозволяет "di" быть нечувствительным к регистру и, таким образом, соответствовать "Dihydrogen" (заглавная D).Поскольку явный захват включен, в первом примере не удается создать группы для ( hydrogen ), поскольку он не использует именованную группу, что является требованием для явного захвата.Второй шаблон имеет 1 группу, поскольку он использует (?<H> hydrogen ).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...