. Net регулярний вираз: що таке слово символ \ w?


77

Просте запитання:
Який шаблон для символу слова \wв c #, .net?

Моя перша думка полягала в тому, що він відповідає, [A-Za-z0-9_]і документація говорить мені:

Клас символів Опис Збіги з шаблоном
\ w Відповідає будь-якому \ w "I", "D", "A", "1", "3"
                   слово символ. в "ID A1.3"

що не дуже корисно.
І, \wсхоже äöü, теж збігається . Що ще? Чи існує краще (точне) визначення?

Відповіді:


115

З документації :

Символ слова: \ w

\wвідповідає символу будь-якого слова. Символ слова є членом будь-якої з категорій Unicode, перелічених у наступній таблиці.

  • Ll (Літера, мала літера)
  • Lu (Літера, великі літери)
  • Lt (Лист, заголовок)
  • Lo (Лист, інше)
  • Lm (Лист, модифікатор)
  • Nd (Число, десяткова цифра)
  • Pc (Пунктуація, роз'єм)
    • Ця категорія включає десять символів, найбільш часто використовуваним є НИЗЬКИЙ символ (_), u + 005F.

Якщо вказано поведінку, сумісну з ECMAScript, \wце еквівалентно [a-zA-Z_0-9].

Дивитися також


1
Отже, якби я використав \w+це, це могло б збігатися з будь-яким словом, яким би божевільним він не був, поки його вміст - або малі, великі літери, цифри 1-9 та кілька (10) спеціальних символів (наприклад, підкреслення). І це було б скороченням для написання чогось на кшталт[a-zA-Z1-9_]+
Ерік Бішард

15

В основному це відповідає усьому, що можна вважати інтуїтивним визначенням букви в різних сценаріях - плюс підкреслення та кілька інших дивних куль.

Ви можете знайти повний список (принаймні для BMP) з таким крихітним фрагментом PowerShell:

0..65535 | ?{([char]$_) -match '\w'} | %{ "$_`: " + [char]$_ }

4

Отже, після деяких досліджень використання '\ w' у .NET еквівалентно:

public static class Extensions { 
    /// <summary>
    /// The word categories.
    /// </summary>
    [NotNull]
    private static readonly HashSet<UnicodeCategory> _wordCategories = new HashCollection<UnicodeCategory>(
                new[]
                {
            UnicodeCategory.DecimalDigitNumber,
            UnicodeCategory.UppercaseLetter,
            UnicodeCategory.ConnectorPunctuation,
            UnicodeCategory.LowercaseLetter,
            UnicodeCategory.OtherLetter,
            UnicodeCategory.TitlecaseLetter,
            UnicodeCategory.ModifierLetter,
            UnicodeCategory.NonSpacingMark,
                });

    /// <summary>
    /// Determines whether the specified character is a word character (equivalent to '\w').
    /// </summary>
    /// <param name="c">The c.</param>
    public static bool IsWord(this char c) => _wordCategories.Contains(char.GetUnicodeCategory(c));
}

Я написав це як метод розширення, щоб його було легко використовувати на будь-якому символі, який cпросто викликається, c.IsWord()який повернеться, trueякщо символ є символом слова. Це має бути значно швидше, ніж використання регулярного виразу.

Цікаво, що це, схоже, не відповідає специфікації .NET, насправді '\ w' відповідає 938 символам 'NonSpacingMark', які не згадуються.

Загалом це збігається з 49 760 із 65 535 символів, тому прості регулярні вирази, часто показані в Інтернеті, є неповними.


Дякую за це, ви заощадили мені багато часу. Я думаю, вам також може знадобитися додати "UnicodeCategory.SpacingCombiningMark" до категорій слів. Я працював з бенгальською (якою я не розмовляю), і цей клас характеру є важливим символом слова.
Д. Тоні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.