Bạn có thể chỉ làm một phần của regex không phân biệt chữ hoa chữ thường không?


100

Tôi đã thấy rất nhiều ví dụ về việc tạo toàn bộ biểu thức chính quy không phân biệt chữ hoa chữ thường. Điều tôi băn khoăn là chỉ một phần của biểu thức không phân biệt chữ hoa chữ thường.

Ví dụ: giả sử tôi có một chuỗi như thế này:

fooFOOfOoFoOBARBARbarbarbAr

Điều gì sẽ xảy ra nếu tôi muốn so khớp tất cả các lần xuất hiện của "foo" bất kể chữ hoa và chữ thường nhưng tôi chỉ muốn so khớp với "BAR" chữ hoa?

Giải pháp lý tưởng sẽ là một cái gì đó hoạt động trên các hương vị regex nhưng tôi cũng muốn nghe những thứ dành riêng cho ngôn ngữ (Cảm ơn Espo )

Biên tập

Liên kết Espo cung cấp rất hữu ích. Có một ví dụ điển hình về việc bật và tắt các công cụ sửa đổi trong biểu thức.

Đối với ví dụ giả định của tôi, tôi có thể làm điều gì đó như sau:

(?i)foo*(?-i)|BAR

điều này làm cho đối sánh không phân biệt chữ hoa chữ thường đối với phần foo của trận đấu.

Điều đó dường như hoạt động trong hầu hết các triển khai regex ngoại trừ Javascript, Python và một số ứng dụng khác (như Espo đã đề cập).

Các ứng dụng lớn mà tôi băn khoăn (Perl, PHP, .NET) đều hỗ trợ thay đổi chế độ nội tuyến.


Câu hỏi này đã được thêm vào Câu hỏi Thường gặp về Cụm từ Thông dụng Stack Overflow , trong "Phần bổ trợ".
aliteralmind

Câu trả lời:


88

Perl cho phép bạn tạo một phần của biểu thức chính quy không phân biệt chữ hoa chữ thường bằng cách sử dụng công cụ sửa đổi mẫu (? I :).

Các hương vị regex hiện đại cho phép bạn chỉ áp dụng các công cụ sửa đổi cho một phần của biểu thức chính quy. Nếu bạn chèn công cụ sửa đổi (? Ism) vào giữa regex, công cụ sửa đổi chỉ áp dụng cho phần của regex ở bên phải của công cụ sửa đổi. Bạn có thể tắt các chế độ bằng cách đặt trước chúng bằng dấu trừ. Tất cả các chế độ sau dấu trừ sẽ bị tắt. Ví dụ: (? I-sm) bật phân biệt chữ hoa chữ thường và tắt cả chế độ một dòng và chế độ nhiều dòng.

Không phải tất cả các hương vị regex đều hỗ trợ điều này. JavaScript và Python áp dụng tất cả các công cụ sửa đổi chế độ cho toàn bộ biểu thức chính quy. Chúng không hỗ trợ cú pháp (? -Ismx), vì việc tắt tùy chọn là vô nghĩa khi các công cụ sửa đổi chế độ áp dụng cho toàn bộ biểu thức chính quy. Tất cả các tùy chọn đều bị tắt theo mặc định.

Bạn có thể nhanh chóng kiểm tra xem hương vị regex bạn đang sử dụng xử lý các công cụ sửa đổi chế độ như thế nào. Regex (? I) te (? - i) st phải khớp với test và TEst, nhưng không phải teST hoặc TEST.

Nguồn


6

Ngôn ngữ của bạn đang sử dụng là gì? Một cách tiêu chuẩn để làm điều này sẽ là một cái gì đó giống như / ([Ff] [Oo] {2} | BAR) / có bật phân biệt chữ hoa chữ thường, nhưng trong Java, ví dụ: có một công cụ sửa đổi phân biệt chữ hoa chữ thường (? I) làm cho tất cả các ký tự bên phải của nó không phân biệt chữ hoa chữ thường và (? -i) bắt buộc phải nhạy cảm. Có thể tìm thấy ví dụ về công cụ sửa đổi regex của Java đó tại đây .


1 Tại sao bận tâm làm cho nó phân biệt dạng chữ khi bạn có thể kết hợp cả hai trường hợp
Nona URBIZ

11
@NonaUrbiz: Bởi vì các biểu hiện (?i)foobarlà có thể đọc được nhiều hơn[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos

1
Và bởi vì nó có thể phát triển cách nhiều hơn nữa lông và phức tạp.
Chop

6

Thật không may, cú pháp cho kết hợp không phân biệt chữ hoa chữ thường không phổ biến. Trong .NET, bạn có thể sử dụng cờ RegexOptions.IgnoreCase hoặc ? I modifier


4

Bạn đã có thể sử dụng

(?:F|f)(?:O|o)(?:O|o)

Dấu?: Trong dấu ngoặc trong .Net có nghĩa là nó không bắt và chỉ được sử dụng để nhóm các điều khoản của | (hoặc) câu lệnh.


26
Không phải "[fF] [oO] [oO]" là lựa chọn thay thế tốt hơn sao? Đối với ví dụ trong tầm tay, bạn thậm chí có thể đi xa tới mức "[fF] [oO] \ {2}" ;-)
Tomalak

4

Đúng là người ta có thể dựa vào các công cụ sửa đổi nội tuyến như được mô tả trong Bật và Tắt Chế độ Chỉ cho một phần của Cụm từ Thông dụng :

Regex (?i)te(?-i)stphải khớp với kiểm tra và TEst, nhưng không teSThoặc TEST.

Tuy nhiên, một tính năng được hỗ trợ nhiều hơn một chút là (?i:...)nhóm bổ trợ nội tuyến (xem Nhịp bổ trợ ). Cú pháp là (?i:, sau đó là mẫu mà bạn muốn tạo không phân biệt dòng tiền, sau đó là a ).

(?i:foo)|BAR

Điều ngược lại : Nếu mô hình của bạn được biên soạn với một trường hợp lựa chọn nhạy cảm và bạn cần phải thực hiện một phần của một trường hợp regex nhạy cảm, bạn thêm -sau ?: (?-i:...).

Ví dụ sử dụng trong các ngôn ngữ khác nhau (bao bọc các kết quả khớp bằng dấu ngoặc nhọn):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")( bản demo )
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( demo ) (lưu ý Python rehỗ trợ các nhóm bổ trợ nội tuyến kể từ Python 3.6)
  • / / - Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>")( bản demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")( bản demo )
  • - $s =~ s/(?i:foo)|BAR/<$&>/g( bản demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')( bản demo )
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)( bản demo )
  • - "fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (sử dụng RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)( demo )

Không được hỗ trợ trong , , , std::regex, , .

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.