.Net regex: ký tự từ \ w là gì?


77

Câu hỏi đơn giản:
Mẫu cho ký tự từ \wtrong c #, .net là gì?

Suy nghĩ đầu tiên của tôi là nó khớp [A-Za-z0-9_]tài liệu cho tôi biết:

Lớp nhân vật Mô tả Mẫu phù hợp
\ w Đối sánh với bất kỳ \ w "I", "D", "A", "1", "3"
                   ký tự từ. trong "ID A1.3"

mà không phải là rất hữu ích.
\wdường như cũng phù hợp äöü. Còn gì nữa? Có định nghĩa nào tốt hơn (chính xác) không?

Câu trả lời:


115

Từ tài liệu :

Ký tự từ: \ w

\wkhớp với bất kỳ ký tự từ nào. Một ký tự từ là thành viên của bất kỳ loại Unicode nào được liệt kê trong bảng sau.

  • Ll (Chữ cái, chữ thường)
  • Lu (Chữ cái, chữ hoa)
  • Lt (Chữ cái, Tiêu đề)
  • Lo (Thư, Khác)
  • Lm (Chữ cái, Bổ ngữ)
  • Nd (Số, chữ số thập phân)
  • Pc (Dấu câu, đầu nối)
    • Danh mục này bao gồm mười ký tự, thường được sử dụng nhất là ký tự LOWLINE (_), u + 005F.

Nếu hành vi tuân thủ ECMAScript được chỉ định, \wtương đương với [a-zA-Z_0-9].

Xem thêm


1
Vì vậy, nếu tôi sử dụng \w+điều này sẽ có khả năng khớp với bất kỳ từ nào dù có điên rồ đến đâu miễn là nội dung của nó là chữ thường, chữ hoa, số 1-9 và một vài (10) ký tự đặc biệt (như _underscore). Và sẽ là viết tắt cho viết một cái gì đó giống như[a-zA-Z1-9_]+
Eric Bishard

15

Về cơ bản, nó phù hợp với mọi thứ có thể được coi là định nghĩa trực quan của chữ cái trong các chữ viết khác nhau - cộng với dấu gạch dưới và một vài điểm kỳ quặc khác.

Bạn có thể tìm thấy một danh sách đầy đủ (ít nhất là cho BMP) với đoạn mã PowerShell nhỏ sau:

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

4

Vì vậy, sau một số nghiên cứu, sử dụng '\ w' trong .NET tương đương với:

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));
}

Tôi đã viết điều này như một phương thức mở rộng để dễ sử dụng trên bất kỳ ký tự nào mà cchỉ cần gọi c.IsWord()nó sẽ trả về truenếu ký tự đó là một ký tự từ. Điều này sẽ nhanh hơn đáng kể so với sử dụng Regex.

Điều thú vị là điều này dường như không khớp với đặc tả .NET, trên thực tế, '\ w' khớp với 938 ký tự 'NonSpacingMark', không được đề cập đến.

Tổng cộng điều này khớp với 49.760 trong số 65.535 ký tự, do đó, regex đơn giản thường được hiển thị trên web là không đầy đủ.


Cảm ơn vì điều này, bạn đã tiết kiệm cho tôi rất nhiều thời gian. Tôi nghĩ rằng bạn cũng có thể cần thêm "UnicodeCategory.SpacingComosystemMark" vào các danh mục từ. Tôi đã làm việc với tiếng Bengali (mà tôi không biết nói) và loại ký tự này là một ký tự từ quan trọng.
D. Tony
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.