Trường hợp biểu hiện thường xuyên không nhạy cảm mà không re.compile?


330

Trong Python, tôi có thể biên dịch một 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 re.compile:

>>> s = 'TeSt'
>>> casesensitive = re.compile('test')
>>> ignorecase = re.compile('test', re.IGNORECASE)
>>> 
>>> print casesensitive.match(s)
None
>>> print ignorecase.match(s)
<_sre.SRE_Match object at 0x02F0B608>

Có cách nào để làm như vậy, nhưng không sử dụng re.compile. Tôi không thể tìm thấy bất cứ điều gì như ihậu tố của Perl (ví dụ m/test/i) trong tài liệu.


1
Bạn có thể tìm thấy một giới thiệu tuyệt vời về các experssoin thông thường tại: python-cference.eu/re.php
2Obe 22/07/17

Câu trả lời:


561

Vượt qua re.IGNORECASEđến flagsparam của search, matchhoặc sub:

re.search('test', 'TeSt', re.IGNORECASE)
re.match('test', 'TeSt', re.IGNORECASE)
re.sub('test', 'xxxx', 'Testing', flags=re.IGNORECASE)

2
re.match('test', 'TeSt', re.IGNORECASE)có thể dẫn đến TypeErrorkhi một trong hai thuộc tính None. Sử dụng try & exceptđể bắt TypeErrorkhớp bởi First_opes == second_opes. Mã mẫu Mã def equal_ignore_case(first_string, second_string): try: return re.match(first_string, second_string, re.IGNORECASE) is not None except (AttributeError, TypeError): return first_string == second_string thử nghiệm
Abhijeet

3
@Abhijeet Bạn thực sự không nên sử dụng thử / ngoại trừ trong trường hợp đó. Chỉ cần kiểm tra nếu bất kỳ chuỗi nào là Noneđầu tiên.
erb

Điều quan trọng là bạn phải dùng tham số được đặt tên flagscho re.subnếu không nó đi re.IGNORECASEđến countlập luận (s cũng có. Stackoverflow.com/questions/42581/... )
L3n95

101

Bạn cũng có thể thực hiện các tìm kiếm không phân biệt chữ hoa chữ thường bằng cách sử dụng tìm kiếm / kết hợp mà không cần cờ IGNORECASE (được thử nghiệm trong Python 2.7.3):

re.search(r'(?i)test', 'TeSt').group()    ## returns 'TeSt'
re.match(r'(?i)test', 'TeSt').group()     ## returns 'TeSt'

2
Tài liệu này không đề cập đến tính năng được thêm vào trong bất kỳ phiên bản cụ thể nào (trái ngược với, nói rằng (?(condition)yes|no)nó được thêm vào 2.4), vì vậy tôi hy vọng nó luôn có sẵn kể từ phiên bản đầu tiên của remô-đun, mà tôi nghĩ đã được thêm vào trong 1,5. Về cơ bản kể từ khi bắt đầu thời gian cho tất cả ý định và mục đích khi nói đến Python. Nó ghi lại khoảng một nửa cách thức thông qua phần đầu tiên của trang này: docs.python.org/2/library/re.html#regular-expression-syntax
ArtOfWarfare

4
Ở đây chúng tôi đi - Tôi đã xem qua tài liệu cho 1.5 và thấy nó đã ghi lại khoảng 60% trong trang này: docs.python.org/release/1.5/lib/. Tôi cũng đã kiểm tra tài liệu 1.4, không đề cập đến tính năng này. Vì vậy, tôi đoán nó đã được thêm vào 1.5, khi regexmô-đun không được dùng trong remô-đun.
ArtOfWarfare

3
Đây là một giải pháp tốt vì nó không cần cờ. Trong trường hợp của tôi, tôi đang lưu trữ các chuỗi tìm kiếm trong Redis và điều này thực sự hữu ích.
Riêng tư

3
@Private: về mặt khái niệm, nó đặt cờ re.I trên toàn bộ regex - không chỉ nhóm chụp trước nó. Xin lưu ý rằng re.match(r'''A ((?i)B) C''', "a b c").group(0)nguyên nhân phù hợp không phân biệt chữ hoa chữ thường trên mọi thứ (A và C), không chỉ trên B! Nếu bạn chỉ muốn khớp chữ hoa chữ thường trên một nhóm chụp cụ thể, thì đây không phải là droid bạn đang tìm kiếm.
smci

1
@Private: có hoàn toàn. Quan điểm của tôi về mặt khái niệm là giống như đặt cờ. Trên toàn bộ regex. Ngay cả các nhóm đi trước nó (!). Không có cú pháp để nói "không phân biệt chữ hoa chữ thường trên các nhóm chụp sau".
smci

53

Dấu không phân biệt chữ hoa chữ thường, (?i)có thể được tích hợp trực tiếp vào mẫu biểu thức chính quy:

>>> import re
>>> s = 'This is one Test, another TEST, and another test.'
>>> re.findall('(?i)test', s)
['Test', 'TEST', 'test']

2
Tùy chọn tốt hơn, làm cho biểu thức chính quy di động trên các nền tảng và mục đích rõ ràng khi khai báo
Sina Madani

1
Cách '(?i)'tiếp cận này cũng có lợi thế là bạn có thể tạo một danh sách các biểu thức chính quy, một số trong đó không phân biệt chữ hoa chữ thường và một số thì không. (Và tất nhiên, bạn có thể ánh xạ re.compilequa danh sách đó nếu bạn thích.)
không chỉ là

@SinaMadani Tôi bối rối. Làm thế nào là di động hơn flags=re.IGNORECASE?
Romain Vincent

10

Bạn cũng có thể xác định trường hợp không nhạy cảm trong quá trình biên dịch mẫu:

pattern = re.compile('FIle:/+(.*)', re.IGNORECASE)

5
Trong câu hỏi OP sử dụng điều này và hỏi liệu có cách nào khác để làm điều đó không.
Peter Wood

6
Hữu ích cho những người cuộn nhanh.
stevek 22/03/2016

6

Trong nhập khẩu

import re

Trong thời gian chạy xử lý:

RE_TEST = r'test'
if re.match(RE_TEST, 'TeSt', re.IGNORECASE):

Cần phải đề cập rằng không sử dụng re.compilelà lãng phí. Mỗi khi phương thức so khớp trên được gọi, biểu thức chính quy sẽ được biên dịch. Đây cũng là thực hành bị lỗi trong các ngôn ngữ lập trình khác. Dưới đây là thực hành tốt hơn.

Trong khởi tạo ứng dụng:

self.RE_TEST = re.compile('test', re.IGNORECASE)

Trong thời gian chạy xử lý:

if self.RE_TEST.match('TeSt'):

1
Cảm ơn bạn! Không ai từng nói về biên dịch, nhưng đó là lựa chọn thông minh nhất!
StefanJCollier

2
OP thực sự yêu cầu một giải pháp không sử dụng re.compile()....
wpercy

4
#'re.IGNORECASE' for case insensitive results short form re.I
#'re.match' returns the first match located from the start of the string. 
#'re.search' returns location of the where the match is found 
#'re.compile' creates a regex object that can be used for multiple matches

 >>> s = r'TeSt'   
 >>> print (re.match(s, r'test123', re.I))
 <_sre.SRE_Match object; span=(0, 4), match='test'>
 # OR
 >>> pattern = re.compile(s, re.I)
 >>> print(pattern.match(r'test123'))
 <_sre.SRE_Match object; span=(0, 4), match='test'>

4

Để thực hiện các hoạt động không phân biệt chữ hoa chữ thường, hãy cung cấp lại.

>>> import re
>>> test = 'UPPER TEXT, lower text, Mixed Text'
>>> re.findall('text', test, flags=re.IGNORECASE)
['TEXT', 'text', 'Text']

và nếu chúng ta muốn thay thế văn bản phù hợp với trường hợp ...

>>> def matchcase(word):
        def replace(m):
            text = m.group()
            if text.isupper():
                return word.upper()
            elif text.islower():
                return word.lower()
            elif text[0].isupper():
                return word.capitalize()
            else:
                return word
        return replace

>>> re.sub('text', matchcase('word'), test, flags=re.IGNORECASE)
'UPPER WORD, lower word, Mixed Word'

1

Nếu bạn muốn thay thế nhưng vẫn giữ phong cách của str trước đó. Điều đó là có thể.

Ví dụ: tô sáng chuỗi "test asdasd TEST asd tEst asdasd".

sentence = "test asdasd TEST asd tEst asdasd"
result = re.sub(
  '(test)', 
  r'<b>\1</b>',  # \1 here indicates first matching group.
  sentence, 
  flags=re.IGNORECASE)

kiểm tra asdasd TEST asd tEst asdasd


0

Đối với biểu thức chính quy không phân biệt chữ hoa chữ thường (Regex): Có hai cách bằng cách thêm vào mã của bạn:

  1. flags=re.IGNORECASE

    Regx3GList = re.search("(WCDMA:)((\d*)(,?))*", txt, **re.IGNORECASE**)
  2. Dấu hiệu không phân biệt chữ hoa chữ thường (?i)

    Regx3GList = re.search("**(?i)**(WCDMA:)((\d*)(,?))*", txt)
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.