На что стоит обратить внимание при замене регулярного выражения без учета регистра? - PullRequest
2 голосов
/ 03 декабря 2009

Я написал следующий код для замены без учета регистра в C #:

Regex.Replace(textBoxText, 
    Regex.Escape(findText), 
    replaceText, 
    RegexOptions.IgnoreCase);

Просто хотел проверить, является ли это правильным подходом, или есть лучший подход, и я пропускаючто-то, о чем мне лучше знать.

Примечание: Пожалуйста, не предоставляйте мне какой-нибудь ручной код, я использовал функцию быстрой замены из codeproject, и этот код вылетает на стороне клиента, и у меня нетспособ узнать, какой вход использовал пользователь.Поэтому я предпочитаю простой, но правильный и надежный метод.

1 Ответ

7 голосов
/ 03 декабря 2009

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

Regex.Replace(textBoxText, 
    Regex.Escape(findText), 
    replaceText, 
    RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

Чтобы использовать другую локаль, вам нужно сделать немного больше фокус-покуса:

// remember current
CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

// set user-selected culture here (in place of "en-US")
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");

// do the regex
Regex.Replace(textBoxText, 
    Regex.Escape(findText), 
    replaceText, 
    RegexOptions.IgnoreCase);

// reset the original culture
Thread.CurrentThread.CurrentCulture = originalCulture;

Обратите внимание, что вы можете включить или выключить нечувствительность к регистру. Это не переключатель, это означает, что:

// these three statements are equivalent and yield the same results:
Regex.Replace("tExT", "[a-z]", "", RegexOptions.IgnoreCase);
Regex.Replace("tExT", "(?i)[a-z]", "", RegexOptions.IgnoreCase);
Regex.Replace("tExT", "(?i)[a-z]", "");

// once IgnoreCase is used, this switches it off for the whole expression...
Regex.Replace("tExT", "(?-i)[a-z]", "", RegexOptions.IgnoreCase);

//...and this can switch it off for only a part of the expression:
Regex.Replace("tExT", "(?:(?-i)[a-z])", "", RegexOptions.IgnoreCase);

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

Обновление: Я ошибочно предположил, что вы не можете переключаться с учетом регистра. Приведенный выше текст редактируется с учетом этого.

...