Làm cách nào để biên dịch regex Python?

Phương thức re.compile(pattern) trả về một đối tượng biểu thức chính quy từ

<re.Match object; span=(0, 6), match='Python'>
0 cung cấp các phương thức regex cơ bản như
<re.Match object; span=(0, 6), match='Python'>
1,
<re.Match object; span=(0, 6), match='Python'>
2 và
<re.Match object; span=(0, 6), match='Python'>
3. Cách tiếp cận hai bước rõ ràng của (1) biên dịch và (2) tìm kiếm mẫu sẽ hiệu quả hơn so với việc gọi, chẳng hạn,
<re.Match object; span=(0, 6), match='Python'>
4 cùng một lúc, nếu bạn so khớp cùng một mẫu nhiều lần vì nó tránh được các phần tổng hợp dư thừa của cùng một mẫu

Tại sao các biểu thức chính quy tồn tại sau bảy thập kỷ gián đoạn công nghệ? . Họ có thể viết trong một dòng mã mà người khác phải mất hàng tá

Biên dịch Python Regex [Sơ lược 7 phút]

Làm cách nào để biên dịch regex Python?

Xem video này trên YouTube

Bài viết này là tất cả về phương thức re.compile(pattern) của thư viện 

<re.Match object; span=(0, 6), match='Python'>
6 của Python. Trước khi chúng ta đi sâu vào
<re.Match object; span=(0, 6), match='Python'>
7, hãy tìm hiểu tổng quan về bốn phương pháp liên quan mà bạn phải hiểu

  • Phương thức
    <re.Match object; span=(0, 6), match='Python'>
    8 trả về một danh sách các chuỗi khớp. Đọc thêm trong hướng dẫn blog của chúng tôi
  • Phương thức
    <re.Match object; span=(0, 6), match='Python'>
    4 trả về một đối tượng so khớp của lần so khớp đầu tiên. Đọc thêm trong hướng dẫn blog của chúng tôi
  • Phương thức
    re.compile(pattern, flags=0)
    0 trả về một đối tượng khớp nếu biểu thức chính quy khớp ở đầu chuỗi. Đọc thêm trong hướng dẫn blog của chúng tôi
  • Phương thức
    re.compile(pattern, flags=0)
    1 trả về một đối tượng khớp nếu biểu thức chính quy khớp với toàn bộ chuỗi. Đọc thêm trong hướng dẫn blog của chúng tôi

bài viết liên quan. Python Regex Superpower – Hướng dẫn cơ bản

Được trang bị tổng quan nhanh này về các phương thức regex quan trọng nhất, hãy cùng trả lời câu hỏi sau

làm thế nào lại. biên dịch () Làm việc trong Python?

Phương thức re.compile(pattern) trả về một đối tượng biểu thức chính quy. Sau đó, bạn sử dụng đối tượng để gọi các phương thức regex quan trọng như

re.compile(pattern, flags=0)
3,
re.compile(pattern, flags=0)
4,
re.compile(pattern, flags=0)
5 và
re.compile(pattern, flags=0)
6

Nói ngắn gọn. Bạn biên dịch mẫu đầu tiên. Bạn tìm kiếm mẫu trong một giây chuỗi

Cách tiếp cận hai bước này hiệu quả hơn so với việc gọi, chẳng hạn như,

<re.Match object; span=(0, 6), match='Python'>
4 cùng một lúc. Đó là, NẾU bạn gọi phương thức
re.compile(pattern, flags=0)
8 nhiều lần trên cùng một mẫu. Tại sao?

Đây là một ví dụ

import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')

Trong cả hai trường hợp, biến khớp chứa đối tượng khớp sau

<re.Match object; span=(0, 6), match='Python'>

Nhưng trong trường hợp đầu tiên, chúng ta có thể tìm thấy mẫu không chỉ trong chuỗi

re.compile(pattern, flags=0)
9‘ mà còn trong các chuỗi khác—mà không cần biên dịch mẫu lặp đi lặp lại nhiều lần

Sự chỉ rõ

re.compile(pattern, flags=0)

Phương thức có tối đa hai đối số

  • <re.Match object; span=(0, 6), match='Python'>
    0. mẫu biểu thức chính quy mà bạn muốn đối sánh
  • def search(pattern, string, flags=0):
        """Scan through string looking for a match to the pattern, returning
        a Match object, or None if no match was found."""
        return _compile(pattern, flags).search(string)
    1 (đối số tùy chọn). một công cụ sửa đổi nâng cao hơn cho phép bạn tùy chỉnh hành vi của chức năng. Bạn muốn biết cách sử dụng những lá cờ đó?

Chúng ta sẽ khám phá những lập luận đó chi tiết hơn sau

Giá trị trả về

Phương thức

def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
2 trả về một đối tượng biểu thức chính quy. Bạn có thể hỏi (và đúng như vậy)

Đối tượng biểu thức chính quy là gì?

Python nội bộ tạo một (từ lớp

def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
3) để chuẩn bị quy trình so khớp mẫu. Bạn có thể gọi các phương thức sau trên đối tượng regex

MethodDescription
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
4Tìm kiếm biểu thức chính quy ở bất kỳ đâu trong chuỗi và trả về một đối tượng khớp hoặc
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
5. Bạn có thể xác định vị trí bắt đầu và kết thúc tìm kiếm.
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
6Tìm kiếm biểu thức chính quy ở đầu chuỗi và trả về một đối tượng khớp hoặc
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
5. Bạn có thể xác định vị trí bắt đầu và kết thúc tìm kiếm.
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
8Khớp regex với toàn bộ chuỗi và trả về một đối tượng khớp hoặc
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
5. Bạn có thể xác định vị trí bắt đầu và kết thúc tìm kiếm.
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
0Chia chuỗi thành danh sách các chuỗi con. Regex là dấu phân cách. Bạn có thể xác định số lần chia tối đa.
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
1Tìm kiếm biểu thức chính quy ở bất kỳ đâu trong chuỗi và trả về danh sách các chuỗi con phù hợp. Bạn có thể xác định vị trí bắt đầu và kết thúc tìm kiếm.
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
2Trả về một trình lặp đi qua tất cả các đối sánh của biểu thức chính quy trong chuỗi (trả về đối tượng đối sánh này đến đối tượng đối sánh khác). Bạn có thể xác định vị trí bắt đầu và kết thúc tìm kiếm.
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
3Trả về một chuỗi mới bằng cách thay thế các lần xuất hiện đầu tiên của regex
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
4 trong chuỗi (từ trái sang phải) bằng chuỗi thay thế
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
5.
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
6Trả về một chuỗi mới bằng cách thay thế các lần xuất hiện đầu tiên của regex
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
4 trong chuỗi (từ trái sang phải) bằng chuỗi thay thế
import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
5. Tuy nhiên, nó trả về một bộ với chuỗi được thay thế là chuỗi đầu tiên và số lần thay thế thành công là giá trị bộ thứ hai

Nếu bạn đã quen thuộc với các phương thức regex cơ bản nhất, bạn sẽ nhận ra rằng tất cả chúng đều xuất hiện trong bảng này. Nhưng có một điểm khác biệt. bạn không cần phải xác định mẫu làm đối số. Ví dụ: phương thức regex

import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
9 sẽ biên dịch nội bộ một đối tượng regex
# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
0 và sau đó gọi
# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
1

Bạn có thể thấy thực tế này trong quá trình triển khai chính thức của phương thức

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
2

def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)

(Nguồn. Kho lưu trữ GitHub của gói lại)

Phương thức

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
3) chỉ là một trình bao bọc để biên dịch mẫu trước và gọi hàm
# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
1 trên đối tượng biểu thức chính quy đã biên dịch
# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
0

Bạn có muốn làm chủ siêu năng lực regex không? . (1) nghiên cứu một chương sách, (2) giải câu đố mật mã và (3) xem video về chương giáo dục

Có đáng để sử dụng lại Python không. biên dịch()?

Không, trong phần lớn các trường hợp, nó không đáng để viết thêm dòng

Xem xét ví dụ sau

import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')

Đừng hiểu lầm ý tôi. Biên dịch mẫu một lần và sử dụng nó nhiều lần trong toàn bộ mã của bạn (e. g. , trong một vòng lặp) đi kèm với lợi ích hiệu suất lớn. Trong một số trường hợp giai thoại, việc biên dịch mẫu trước tiên dẫn đến tốc độ tăng gấp 10 lần đến 50 lần so với việc biên dịch lặp đi lặp lại

Nhưng lý do nó không đáng để thêm dòng là thư viện re của Python đi kèm với bộ đệm bên trong. Tại thời điểm viết bài này, bộ đệm có giới hạn lên tới 512 đối tượng regex được biên dịch. Vì vậy, trong 512 lần đầu tiên, bạn có thể chắc chắn khi gọi

import re

# These two lines ...
regex = re.compile('Py...n')
match = regex.search('Python is great')

# .. are equivalent to ...
match = re.search('Py...n', 'Python is great')
9 rằng bộ đệm đã chứa mẫu đã biên dịch

Đây là đoạn mã có liên quan từ re's GitHub repo

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p

Bạn có thể tìm thấy những điểm mà bộ đệm được khởi tạo và sử dụng không?

Trong hầu hết các trường hợp, bạn không cần phải biên dịch một mẫu, trong một số trường hợp, bạn nên. Những điều này theo trực tiếp từ việc thực hiện trước đó

  • Bạn có hơn
    # --------------------------------------------------------------------
    # internals
    
    _cache = {}  # ordered!
    
    _MAXCACHE = 512
    def _compile(pattern, flags):
        # internal: compile pattern
        if isinstance(flags, RegexFlag):
            flags = flags.value
        try:
            return _cache[type(pattern), pattern, flags]
        except KeyError:
            pass
        if isinstance(pattern, Pattern):
            if flags:
                raise ValueError(
                    "cannot process flags argument with a compiled pattern")
            return pattern
        if not sre_compile.isstring(pattern):
            raise TypeError("first argument must be string or compiled pattern")
        p = sre_compile.compile(pattern, flags)
        if not (flags & DEBUG):
            if len(_cache) >= _MAXCACHE:
                # Drop the oldest item
                try:
                    del _cache[next(iter(_cache))]
                except (StopIteration, RuntimeError, KeyError):
                    pass
            _cache[type(pattern), pattern, flags] = p
        return p
    7 mẫu trong mã của mình
  • Bạn có hơn
    # --------------------------------------------------------------------
    # internals
    
    _cache = {}  # ordered!
    
    _MAXCACHE = 512
    def _compile(pattern, flags):
        # internal: compile pattern
        if isinstance(flags, RegexFlag):
            flags = flags.value
        try:
            return _cache[type(pattern), pattern, flags]
        except KeyError:
            pass
        if isinstance(pattern, Pattern):
            if flags:
                raise ValueError(
                    "cannot process flags argument with a compiled pattern")
            return pattern
        if not sre_compile.isstring(pattern):
            raise TypeError("first argument must be string or compiled pattern")
        p = sre_compile.compile(pattern, flags)
        if not (flags & DEBUG):
            if len(_cache) >= _MAXCACHE:
                # Drop the oldest item
                try:
                    del _cache[next(iter(_cache))]
                except (StopIteration, RuntimeError, KeyError):
                    pass
            _cache[type(pattern), pattern, flags] = p
        return p
    7 mẫu khác nhau giữa hai trường hợp mẫu giống nhau. Chỉ trong trường hợp này, bạn sẽ thấy "lỗi bộ nhớ cache" trong đó bộ nhớ cache đã xóa các phiên bản mẫu có vẻ cũ để nhường chỗ cho các mẫu mới hơn
  • Bạn sử dụng lại mẫu nhiều lần. Bởi vì nếu không, sẽ không có ý nghĩa gì khi sử dụng bộ nhớ thưa thớt để lưu chúng vào bộ nhớ của bạn
  • (Ngay cả khi đó, nó chỉ có thể hữu ích nếu các mẫu tương đối phức tạp. Nếu không, bạn sẽ không thấy nhiều lợi ích về hiệu suất trong thực tế. )

Tóm lại, việc biên dịch mẫu trước và lưu trữ mẫu đã biên dịch trong một biến để sử dụng sau này thường không có gì khác ngoài việc “tối ưu hóa sớm”—một trong những sai lầm chết người của các lập trình viên mới bắt đầu và trung cấp

Làm gì lại. compile() Thực sự làm?

Nó không giống như nhiều, phải không? . Và, tất nhiên, phù hợp với mô hình là phần khó khăn. Nhưng một trình biên dịch hợp lý sẽ giúp ích rất nhiều trong việc chuẩn bị mẫu để khớp một cách hiệu quả bởi công cụ biểu thức chính quy — công việc mà lẽ ra công cụ biểu thức chính quy phải thực hiện

Phương thức

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
9 của Regex thực hiện rất nhiều việc như

  • Kết hợp hai ký tự tiếp theo trong biểu thức chính quy nếu chúng cùng biểu thị một ký hiệu đặc biệt, chẳng hạn như một số ký hiệu Hy Lạp
  • Chuẩn bị regex để bỏ qua chữ hoa và chữ thường
  • Kiểm tra các mẫu nhất định (nhỏ hơn) trong biểu thức chính quy
  • Phân tích các nhóm phù hợp trong biểu thức chính quy được đặt trong ngoặc đơn

Đây là cách triển khai phương pháp

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
9—có vẻ phức tạp hơn dự kiến, phải không?

def _compile(code, pattern, flags):
    # internal: compile a (sub)pattern
    emit = code.append
    _len = len
    LITERAL_CODES = _LITERAL_CODES
    REPEATING_CODES = _REPEATING_CODES
    SUCCESS_CODES = _SUCCESS_CODES
    ASSERT_CODES = _ASSERT_CODES
    iscased = None
    tolower = None
    fixes = None
    if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE:
        if flags & SRE_FLAG_UNICODE:
            iscased = _sre.unicode_iscased
            tolower = _sre.unicode_tolower
            fixes = _ignorecase_fixes
        else:
            iscased = _sre.ascii_iscased
            tolower = _sre.ascii_tolower
    for op, av in pattern:
        if op in LITERAL_CODES:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
                emit(av)
            elif flags & SRE_FLAG_LOCALE:
                emit(OP_LOCALE_IGNORE[op])
                emit(av)
            elif not iscased(av):
                emit(op)
                emit(av)
            else:
                lo = tolower(av)
                if not fixes:  # ascii
                    emit(OP_IGNORE[op])
                    emit(lo)
                elif lo not in fixes:
                    emit(OP_UNICODE_IGNORE[op])
                    emit(lo)
                else:
                    emit(IN_UNI_IGNORE)
                    skip = _len(code); emit(0)
                    if op is NOT_LITERAL:
                        emit(NEGATE)
                    for k in (lo,) + fixes[lo]:
                        emit(LITERAL)
                        emit(k)
                    emit(FAILURE)
                    code[skip] = _len(code) - skip
        elif op is IN:
            charset, hascased = _optimize_charset(av, iscased, tolower, fixes)
            if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE:
                emit(IN_LOC_IGNORE)
            elif not hascased:
                emit(IN)
            elif not fixes:  # ascii
                emit(IN_IGNORE)
            else:
                emit(IN_UNI_IGNORE)
            skip = _len(code); emit(0)
            _compile_charset(charset, flags, code)
            code[skip] = _len(code) - skip
        elif op is ANY:
            if flags & SRE_FLAG_DOTALL:
                emit(ANY_ALL)
            else:
                emit(ANY)
        elif op in REPEATING_CODES:
            if flags & SRE_FLAG_TEMPLATE:
                raise error("internal: unsupported template operator %r" % (op,))
            if _simple(av[2]):
                if op is MAX_REPEAT:
                    emit(REPEAT_ONE)
                else:
                    emit(MIN_REPEAT_ONE)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                emit(SUCCESS)
                code[skip] = _len(code) - skip
            else:
                emit(REPEAT)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                code[skip] = _len(code) - skip
                if op is MAX_REPEAT:
                    emit(MAX_UNTIL)
                else:
                    emit(MIN_UNTIL)
        elif op is SUBPATTERN:
            group, add_flags, del_flags, p = av
            if group:
                emit(MARK)
                emit((group-1)*2)
            # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags))
            _compile(code, p, _combine_flags(flags, add_flags, del_flags))
            if group:
                emit(MARK)
                emit((group-1)*2+1)
        elif op in SUCCESS_CODES:
            emit(op)
        elif op in ASSERT_CODES:
            emit(op)
            skip = _len(code); emit(0)
            if av[0] >= 0:
                emit(0) # look ahead
            else:
                lo, hi = av[1].getwidth()
                if lo != hi:
                    raise error("look-behind requires fixed-width pattern")
                emit(lo) # look behind
            _compile(code, av[1], flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is CALL:
            emit(op)
            skip = _len(code); emit(0)
            _compile(code, av, flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is AT:
            emit(op)
            if flags & SRE_FLAG_MULTILINE:
                av = AT_MULTILINE.get(av, av)
            if flags & SRE_FLAG_LOCALE:
                av = AT_LOCALE.get(av, av)
            elif flags & SRE_FLAG_UNICODE:
                av = AT_UNICODE.get(av, av)
            emit(av)
        elif op is BRANCH:
            emit(op)
            tail = []
            tailappend = tail.append
            for av in av[1]:
                skip = _len(code); emit(0)
                # _compile_info(code, av, flags)
                _compile(code, av, flags)
                emit(JUMP)
                tailappend(_len(code)); emit(0)
                code[skip] = _len(code) - skip
            emit(FAILURE) # end of branch
            for tail in tail:
                code[tail] = _len(code) - tail
        elif op is CATEGORY:
            emit(op)
            if flags & SRE_FLAG_LOCALE:
                av = CH_LOCALE[av]
            elif flags & SRE_FLAG_UNICODE:
                av = CH_UNICODE[av]
            emit(av)
        elif op is GROUPREF:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
            elif flags & SRE_FLAG_LOCALE:
                emit(GROUPREF_LOC_IGNORE)
            elif not fixes:  # ascii
                emit(GROUPREF_IGNORE)
            else:
                emit(GROUPREF_UNI_IGNORE)
            emit(av-1)
        elif op is GROUPREF_EXISTS:
            emit(op)
            emit(av[0]-1)
            skipyes = _len(code); emit(0)
            _compile(code, av[1], flags)
            if av[2]:
                emit(JUMP)
                skipno = _len(code); emit(0)
                code[skipyes] = _len(code) - skipyes + 1
                _compile(code, av[2], flags)
                code[skipno] = _len(code) - skipno
            else:
                code[skipyes] = _len(code) - skipyes + 1
        else:
            raise error("internal: unsupported operand type %r" % (op,))

Không cần phải hiểu mọi thứ trong mã này. Chỉ cần lưu ý rằng tất cả công việc này sẽ phải được thực hiện bởi công cụ biểu thức chính quy tại "thời gian chạy phù hợp" nếu bạn không biên dịch mẫu trước. Nếu chúng ta chỉ có thể làm điều đó một lần, thì đó chắc chắn là một kết quả thấp để tối ưu hóa hiệu suất—đặc biệt là đối với các mẫu biểu thức chính quy dài

Làm cách nào để sử dụng đối số cờ tùy chọn?

Như bạn đã thấy trong đặc tả, phương thức

# --------------------------------------------------------------------
# internals

_cache = {}  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    except KeyError:
        pass
    if isinstance(pattern, Pattern):
        if flags:
            raise ValueError(
                "cannot process flags argument with a compiled pattern")
        return pattern
    if not sre_compile.isstring(pattern):
        raise TypeError("first argument must be string or compiled pattern")
    p = sre_compile.compile(pattern, flags)
    if not (flags & DEBUG):
        if len(_cache) >= _MAXCACHE:
            # Drop the oldest item
            try:
                del _cache[next(iter(_cache))]
            except (StopIteration, RuntimeError, KeyError):
                pass
        _cache[type(pattern), pattern, flags] = p
    return p
9 đi kèm với đối số thứ ba tùy chọn
def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)
1

re.compile(pattern, flags=0)

Mục đích của đối số flags là gì?

Cờ cho phép bạn kiểm soát công cụ biểu thức chính quy. Bởi vì biểu thức chính quy rất mạnh nên chúng là một cách hữu ích để bật và tắt một số tính năng nhất định (ví dụ: có nên bỏ qua cách viết hoa khi đối sánh biểu thức chính quy của bạn hay không)

Cú phápÝ nghĩa. ASCIINếu bạn không sử dụng cờ này, các ký hiệu biểu thức chính quy Python đặc biệt \w, \W, \b, \B, \d, \D, \s và \S sẽ khớp với các ký tự Unicode. Nếu bạn sử dụng cờ này, những ký hiệu đặc biệt đó sẽ chỉ khớp với các ký tự ASCII — như tên gợi ý. lại. Tương tự như lại. ASCIIre. GỠ LỖI Nếu bạn sử dụng cờ này, Python sẽ in một số thông tin hữu ích vào trình bao để giúp bạn gỡ lỗi biểu thức chính quy của mình. lại. IGNORECASENếu bạn sử dụng cờ này, công cụ regex sẽ thực hiện khớp không phân biệt chữ hoa chữ thường. Vì vậy, nếu bạn đang tìm kiếm [A-Z], nó cũng sẽ khớp với [a-z]. lại. Giống như lại. BỎ QUA. ĐỊA PHƯƠNGKhông sử dụng cờ này — chưa bao giờ. Nó không được dùng nữa—ý tưởng là thực hiện so khớp không phân biệt chữ hoa chữ thường tùy thuộc vào ngôn ngữ hiện tại của bạn. Nhưng nó không đáng tin cậy. lại. LGiống như lại. ĐỊA PHƯƠNGre. MULTILINECờ này bật tính năng sau. biểu thức chính quy bắt đầu chuỗi '^' khớp ở đầu mỗi dòng (thay vì chỉ ở đầu chuỗi). Điều tương tự cũng xảy ra đối với biểu thức chính quy cuối chuỗi '$' hiện cũng khớp ở cuối mỗi dòng trong một chuỗi nhiều dòng. lại. Tương tự như lại. MULTILINEre. DOTALLKhông sử dụng cờ này, dấu chấm regex ‘. ' khớp với tất cả các ký tự ngoại trừ ký tự xuống dòng 'n'. Bật cờ này để thực sự khớp với tất cả các ký tự kể cả ký tự xuống dòng. lại. Tương tự như lại. dotallre. ĐỘNG TỪ Để cải thiện khả năng đọc của các biểu thức chính quy phức tạp, bạn có thể muốn cho phép nhận xét và định dạng (nhiều dòng) của chính biểu thức chính quy. Điều này là có thể với cờ này. tất cả các ký tự khoảng trắng và các dòng bắt đầu bằng ký tự '#' đều bị bỏ qua trong biểu thức chính quy. lại. XSGiống như lại. RÕ RÀNG

Đây là cách bạn sử dụng nó trong một ví dụ thực tế

import re

text = 'Python is great (python really is)'

regex = re.compile('Py...n', flags=re.IGNORECASE)

matches = regex.findall(text)
print(matches)
# ['Python', 'python']

Mặc dù biểu thức chính quy của bạn

def _compile(code, pattern, flags):
    # internal: compile a (sub)pattern
    emit = code.append
    _len = len
    LITERAL_CODES = _LITERAL_CODES
    REPEATING_CODES = _REPEATING_CODES
    SUCCESS_CODES = _SUCCESS_CODES
    ASSERT_CODES = _ASSERT_CODES
    iscased = None
    tolower = None
    fixes = None
    if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE:
        if flags & SRE_FLAG_UNICODE:
            iscased = _sre.unicode_iscased
            tolower = _sre.unicode_tolower
            fixes = _ignorecase_fixes
        else:
            iscased = _sre.ascii_iscased
            tolower = _sre.ascii_tolower
    for op, av in pattern:
        if op in LITERAL_CODES:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
                emit(av)
            elif flags & SRE_FLAG_LOCALE:
                emit(OP_LOCALE_IGNORE[op])
                emit(av)
            elif not iscased(av):
                emit(op)
                emit(av)
            else:
                lo = tolower(av)
                if not fixes:  # ascii
                    emit(OP_IGNORE[op])
                    emit(lo)
                elif lo not in fixes:
                    emit(OP_UNICODE_IGNORE[op])
                    emit(lo)
                else:
                    emit(IN_UNI_IGNORE)
                    skip = _len(code); emit(0)
                    if op is NOT_LITERAL:
                        emit(NEGATE)
                    for k in (lo,) + fixes[lo]:
                        emit(LITERAL)
                        emit(k)
                    emit(FAILURE)
                    code[skip] = _len(code) - skip
        elif op is IN:
            charset, hascased = _optimize_charset(av, iscased, tolower, fixes)
            if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE:
                emit(IN_LOC_IGNORE)
            elif not hascased:
                emit(IN)
            elif not fixes:  # ascii
                emit(IN_IGNORE)
            else:
                emit(IN_UNI_IGNORE)
            skip = _len(code); emit(0)
            _compile_charset(charset, flags, code)
            code[skip] = _len(code) - skip
        elif op is ANY:
            if flags & SRE_FLAG_DOTALL:
                emit(ANY_ALL)
            else:
                emit(ANY)
        elif op in REPEATING_CODES:
            if flags & SRE_FLAG_TEMPLATE:
                raise error("internal: unsupported template operator %r" % (op,))
            if _simple(av[2]):
                if op is MAX_REPEAT:
                    emit(REPEAT_ONE)
                else:
                    emit(MIN_REPEAT_ONE)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                emit(SUCCESS)
                code[skip] = _len(code) - skip
            else:
                emit(REPEAT)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                code[skip] = _len(code) - skip
                if op is MAX_REPEAT:
                    emit(MAX_UNTIL)
                else:
                    emit(MIN_UNTIL)
        elif op is SUBPATTERN:
            group, add_flags, del_flags, p = av
            if group:
                emit(MARK)
                emit((group-1)*2)
            # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags))
            _compile(code, p, _combine_flags(flags, add_flags, del_flags))
            if group:
                emit(MARK)
                emit((group-1)*2+1)
        elif op in SUCCESS_CODES:
            emit(op)
        elif op in ASSERT_CODES:
            emit(op)
            skip = _len(code); emit(0)
            if av[0] >= 0:
                emit(0) # look ahead
            else:
                lo, hi = av[1].getwidth()
                if lo != hi:
                    raise error("look-behind requires fixed-width pattern")
                emit(lo) # look behind
            _compile(code, av[1], flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is CALL:
            emit(op)
            skip = _len(code); emit(0)
            _compile(code, av, flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is AT:
            emit(op)
            if flags & SRE_FLAG_MULTILINE:
                av = AT_MULTILINE.get(av, av)
            if flags & SRE_FLAG_LOCALE:
                av = AT_LOCALE.get(av, av)
            elif flags & SRE_FLAG_UNICODE:
                av = AT_UNICODE.get(av, av)
            emit(av)
        elif op is BRANCH:
            emit(op)
            tail = []
            tailappend = tail.append
            for av in av[1]:
                skip = _len(code); emit(0)
                # _compile_info(code, av, flags)
                _compile(code, av, flags)
                emit(JUMP)
                tailappend(_len(code)); emit(0)
                code[skip] = _len(code) - skip
            emit(FAILURE) # end of branch
            for tail in tail:
                code[tail] = _len(code) - tail
        elif op is CATEGORY:
            emit(op)
            if flags & SRE_FLAG_LOCALE:
                av = CH_LOCALE[av]
            elif flags & SRE_FLAG_UNICODE:
                av = CH_UNICODE[av]
            emit(av)
        elif op is GROUPREF:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
            elif flags & SRE_FLAG_LOCALE:
                emit(GROUPREF_LOC_IGNORE)
            elif not fixes:  # ascii
                emit(GROUPREF_IGNORE)
            else:
                emit(GROUPREF_UNI_IGNORE)
            emit(av-1)
        elif op is GROUPREF_EXISTS:
            emit(op)
            emit(av[0]-1)
            skipyes = _len(code); emit(0)
            _compile(code, av[1], flags)
            if av[2]:
                emit(JUMP)
                skipno = _len(code); emit(0)
                code[skipyes] = _len(code) - skipyes + 1
                _compile(code, av[2], flags)
                code[skipno] = _len(code) - skipno
            else:
                code[skipyes] = _len(code) - skipyes + 1
        else:
            raise error("internal: unsupported operand type %r" % (op,))
3 là chữ hoa, nhưng chúng tôi bỏ qua cách viết hoa bằng cách sử dụng cờ
def _compile(code, pattern, flags):
    # internal: compile a (sub)pattern
    emit = code.append
    _len = len
    LITERAL_CODES = _LITERAL_CODES
    REPEATING_CODES = _REPEATING_CODES
    SUCCESS_CODES = _SUCCESS_CODES
    ASSERT_CODES = _ASSERT_CODES
    iscased = None
    tolower = None
    fixes = None
    if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE:
        if flags & SRE_FLAG_UNICODE:
            iscased = _sre.unicode_iscased
            tolower = _sre.unicode_tolower
            fixes = _ignorecase_fixes
        else:
            iscased = _sre.ascii_iscased
            tolower = _sre.ascii_tolower
    for op, av in pattern:
        if op in LITERAL_CODES:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
                emit(av)
            elif flags & SRE_FLAG_LOCALE:
                emit(OP_LOCALE_IGNORE[op])
                emit(av)
            elif not iscased(av):
                emit(op)
                emit(av)
            else:
                lo = tolower(av)
                if not fixes:  # ascii
                    emit(OP_IGNORE[op])
                    emit(lo)
                elif lo not in fixes:
                    emit(OP_UNICODE_IGNORE[op])
                    emit(lo)
                else:
                    emit(IN_UNI_IGNORE)
                    skip = _len(code); emit(0)
                    if op is NOT_LITERAL:
                        emit(NEGATE)
                    for k in (lo,) + fixes[lo]:
                        emit(LITERAL)
                        emit(k)
                    emit(FAILURE)
                    code[skip] = _len(code) - skip
        elif op is IN:
            charset, hascased = _optimize_charset(av, iscased, tolower, fixes)
            if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE:
                emit(IN_LOC_IGNORE)
            elif not hascased:
                emit(IN)
            elif not fixes:  # ascii
                emit(IN_IGNORE)
            else:
                emit(IN_UNI_IGNORE)
            skip = _len(code); emit(0)
            _compile_charset(charset, flags, code)
            code[skip] = _len(code) - skip
        elif op is ANY:
            if flags & SRE_FLAG_DOTALL:
                emit(ANY_ALL)
            else:
                emit(ANY)
        elif op in REPEATING_CODES:
            if flags & SRE_FLAG_TEMPLATE:
                raise error("internal: unsupported template operator %r" % (op,))
            if _simple(av[2]):
                if op is MAX_REPEAT:
                    emit(REPEAT_ONE)
                else:
                    emit(MIN_REPEAT_ONE)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                emit(SUCCESS)
                code[skip] = _len(code) - skip
            else:
                emit(REPEAT)
                skip = _len(code); emit(0)
                emit(av[0])
                emit(av[1])
                _compile(code, av[2], flags)
                code[skip] = _len(code) - skip
                if op is MAX_REPEAT:
                    emit(MAX_UNTIL)
                else:
                    emit(MIN_UNTIL)
        elif op is SUBPATTERN:
            group, add_flags, del_flags, p = av
            if group:
                emit(MARK)
                emit((group-1)*2)
            # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags))
            _compile(code, p, _combine_flags(flags, add_flags, del_flags))
            if group:
                emit(MARK)
                emit((group-1)*2+1)
        elif op in SUCCESS_CODES:
            emit(op)
        elif op in ASSERT_CODES:
            emit(op)
            skip = _len(code); emit(0)
            if av[0] >= 0:
                emit(0) # look ahead
            else:
                lo, hi = av[1].getwidth()
                if lo != hi:
                    raise error("look-behind requires fixed-width pattern")
                emit(lo) # look behind
            _compile(code, av[1], flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is CALL:
            emit(op)
            skip = _len(code); emit(0)
            _compile(code, av, flags)
            emit(SUCCESS)
            code[skip] = _len(code) - skip
        elif op is AT:
            emit(op)
            if flags & SRE_FLAG_MULTILINE:
                av = AT_MULTILINE.get(av, av)
            if flags & SRE_FLAG_LOCALE:
                av = AT_LOCALE.get(av, av)
            elif flags & SRE_FLAG_UNICODE:
                av = AT_UNICODE.get(av, av)
            emit(av)
        elif op is BRANCH:
            emit(op)
            tail = []
            tailappend = tail.append
            for av in av[1]:
                skip = _len(code); emit(0)
                # _compile_info(code, av, flags)
                _compile(code, av, flags)
                emit(JUMP)
                tailappend(_len(code)); emit(0)
                code[skip] = _len(code) - skip
            emit(FAILURE) # end of branch
            for tail in tail:
                code[tail] = _len(code) - tail
        elif op is CATEGORY:
            emit(op)
            if flags & SRE_FLAG_LOCALE:
                av = CH_LOCALE[av]
            elif flags & SRE_FLAG_UNICODE:
                av = CH_UNICODE[av]
            emit(av)
        elif op is GROUPREF:
            if not flags & SRE_FLAG_IGNORECASE:
                emit(op)
            elif flags & SRE_FLAG_LOCALE:
                emit(GROUPREF_LOC_IGNORE)
            elif not fixes:  # ascii
                emit(GROUPREF_IGNORE)
            else:
                emit(GROUPREF_UNI_IGNORE)
            emit(av-1)
        elif op is GROUPREF_EXISTS:
            emit(op)
            emit(av[0]-1)
            skipyes = _len(code); emit(0)
            _compile(code, av[1], flags)
            if av[2]:
                emit(JUMP)
                skipno = _len(code); emit(0)
                code[skipyes] = _len(code) - skipyes + 1
                _compile(code, av[2], flags)
                code[skipno] = _len(code) - skipno
            else:
                code[skipyes] = _len(code) - skipyes + 1
        else:
            raise error("internal: unsupported operand type %r" % (op,))
4

Đi đâu từ đây?

Bạn đã tìm hiểu về phương thức re.compile(pattern) chuẩn bị mẫu biểu thức chính quy—và trả về một đối tượng biểu thức chính quy mà bạn có thể sử dụng nhiều lần trong mã của mình

Học Python khó. Nhưng nếu bạn gian lận, nó không khó như nó phải thế

Tải xuống 8 Bảng cheat Python miễn phí ngay bây giờ

Các kỹ sư của Google, Facebook và Amazon là những bậc thầy về biểu thức chính quy. Nếu bạn cũng muốn trở thành một người như vậy, hãy xem cuốn sách mới của chúng tôi. Cách thông minh nhất để học Python Regex (Amazon Kindle/Print, mở trong tab mới)

Làm cách nào để biên dịch regex Python?

Chris

Trong khi làm việc với tư cách là một nhà nghiên cứu trong các hệ thống phân tán, Dr. Christian Mayer tìm thấy tình yêu của mình với việc dạy sinh viên khoa học máy tính

Để giúp sinh viên đạt được mức độ thành công Python cao hơn, anh ấy đã thành lập trang web giáo dục lập trình Finxter. com. Ông là tác giả của cuốn sách lập trình nổi tiếng Python One-Liners (NoStarch 2020), đồng tác giả của loạt sách tự xuất bản Coffee Break Python, người đam mê khoa học máy tính, cộng tác viên tự do và chủ sở hữu của một trong 10 blog Python lớn nhất thế giới

Niềm đam mê của anh ấy là viết, đọc và mã hóa. Nhưng niềm đam mê lớn nhất của anh ấy là phục vụ các lập trình viên đầy tham vọng thông qua Finxter và giúp họ nâng cao kỹ năng của mình. Bạn có thể tham gia học viện email miễn phí của anh ấy tại đây

Biên dịch trong biểu thức chính quy là gì?

Hàm compile() nhận đầu vào là một biểu thức chính quy đơn giản và tạo ra một biểu thức đã biên dịch có thể được sử dụng với các hàm step() và advance() . Chuỗi tham số đầu tiên không bao giờ được sử dụng rõ ràng bởi compile(). Nó là một con trỏ tới một chuỗi ký tự xác định một biểu thức chính quy nguồn.

Regex được xử lý như thế nào trong Python?

Python cung cấp hai thao tác nguyên thủy khác nhau dựa trên các biểu thức chính quy. match chỉ kiểm tra sự khớp ở đầu chuỗi, trong khi tìm kiếm kiểm tra sự khớp ở bất kỳ đâu trong chuỗi (đây là điều mà Perl thực hiện theo mặc định).

?= Trong Python regex là gì?

(?=. ) là khẳng định nhìn trước tích cực . Nó khớp nếu có phần trong ngoặc đơn sau ?= khớp ở vị trí hiện tại, nhưng nó sẽ không sử dụng bất kỳ ký tự nào cho khớp.

Python regex có được tích hợp sẵn không?

Mô-đun RegEx . Python has a built-in package called re , which can be used to work with Regular Expressions.