Làm cách nào để sử dụng biểu thức chính quy không phân biệt chữ hoa chữ thường trong Go?


84

Tất nhiên, bây giờ tôi có thể viết biểu thức chính quy của mình để xử lý cả hai trường hợp, chẳng hạn như regexp.Compile("[a-zA-Z]"), nhưng biểu thức chính quy của tôi được xây dựng từ một chuỗi do người dùng cung cấp:

reg, err := regexp.Compile(strings.Replace(s.Name, " ", "[ \\._-]", -1))

Trong trường hợp s.Namelà tên. Đó có thể là một cái gì đó giống như 'North by Northwest'. Bây giờ, giải pháp rõ ràng nhất đối với tôi là xem qua từng ký tự s.Namevà viết '[nN]' cho mỗi chữ cái:

for i := 0; i < len(s.Name); i++ {
  if s.Name[i] == " " {
    fmt.Fprintf(str, "%s[ \\._-]", str);
  } else {
    fmt.Fprintf(str, "%s[%s%s]", str, strings.ToLower(s.Name[i]), strings.ToUpper(s.Name[i]))
  }
}

Nhưng tôi cảm thấy đây là một giải pháp không thanh lịch. Tốc độ thực sự không phải là vấn đề đáng lo ngại, nhưng tôi cần biết nếu có cách khác.

Câu trả lời:


171

Bạn có thể đặt cờ không phân biệt chữ hoa chữ thường làm mục đầu tiên trong regex.

Bạn làm điều này bằng cách thêm "(?i)"vào đầu của một regex.

reg, err := regexp.Compile("(?i)"+strings.Replace(s.Name, " ", "[ \\._-]", -1))

Đối với một regex cố định, nó sẽ như thế này.

r := regexp.MustCompile(`(?i)CaSe`)

Để biết thêm thông tin về các cờ, hãy tìm kiếm regexp/syntaxtài liệu gói (hoặc tài liệu cú pháp ) cho thuật ngữ "cờ".


4
Nhưng tôi thấy cách này quá chậm, khi có nhiều dữ liệu. Vì gọi unicode.SimpleFold trong regexp.Match, vì vậy tôi khuyên bạn nên thay đổi các ký tự thành chữ hoa và sau đó sử dụng regexp để khớp. Đây là tốc độ. Sau đây là dữ liệu thời gian: `` #By (? I) regexp để bỏ qua trường hợp XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / frameworks -f Code / framework 1271,94s user 7.32s system 97% cpu 21: 54,95 tổng số #By toUpper và khớp XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / framework -f Code / framework 263,87 giây người dùng 8,99 giây Hệ thống 110% cpu 4: 06,44 tổng cộng '' '
QJGui

1
Dường như làm chậm hiệu suất cho regexp case-insensitive được một lỗi được biết rằng đã được cố định trong những tháng sau đây: github.com/golang/go/issues/13288
Dan Esparza



4

Sử dụng icờ. Trích dẫn tài liệu mẹo :

Phân nhóm:

(re)           numbered capturing group
(?P<name>re)   named & numbered capturing group
(?:re)         non-capturing group
(?flags)       set flags within current group; non-capturing
(?flags:re)    set flags during re; non-capturing

Cú pháp cờ là xyz (set) hoặc -xyz (clear) hoặc xy-z (set xy, clear z). Các lá cờ là:

i              case-insensitive (default false)
m              multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)
s              let . match \n (default false)
U              ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false)

22
Tôi nên đặt những chữ i, m, s và U ở đâu trong mã?
Qian Chen

25
Câu trả lời này không hữu ích như tài liệu. Rất may, có một ví dụ hoạt động bên dưới.
đoạt giải thưởng
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.