Hướng dẫn python regex replace multiple patterns - python regex thay thế nhiều mẫu

Based on Eric's great answer, I came up with a more general solution that is capable of handling capturing groups and backreferences:

import re
from itertools import islice

def multiple_replace[s, repl_dict]:
    groups_no = [re.compile[pattern].groups for pattern in repl_dict]

    def repl_func[m]:
        all_groups = m.groups[]

        # Use 'i' as the index within 'all_groups' and 'j' as the main
        # group index.
        i, j = 0, 0

        while i < len[all_groups] and all_groups[i] is None:
            # Skip the inner groups and move on to the next group.
            i += [groups_no[j] + 1]

            # Advance the main group index.
            j += 1

        # Extract the pattern and replacement at the j-th position.
        pattern, repl = next[islice[repl_dict.items[], j, j + 1]]

        return re.sub[pattern, repl, all_groups[i]]

    # Create the full pattern using the keys of 'repl_dict'.
    full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    return re.sub[full_pattern, repl_func, s]

Example. Calling the above with

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}

gives:

>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'

For a more efficient solution, one can create a simple wrapper to precompute groups_no and

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
0, e.g.

import re
from itertools import islice

class ReplWrapper:
    def __init__[self, repl_dict]:
        self.repl_dict = repl_dict
        self.groups_no = [re.compile[pattern].groups for pattern in repl_dict]
        self.full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    def get_pattern_repl[self, pos]:
        return next[islice[self.repl_dict.items[], pos, pos + 1]]

    def multiple_replace[self, s]:
        def repl_func[m]:
            all_groups = m.groups[]

            # Use 'i' as the index within 'all_groups' and 'j' as the main
            # group index.
            i, j = 0, 0

            while i < len[all_groups] and all_groups[i] is None:
                # Skip the inner groups and move on to the next group.
                i += [self.groups_no[j] + 1]

                # Advance the main group index.
                j += 1

            return re.sub[*self.get_pattern_repl[j], all_groups[i]]

        return re.sub[self.full_pattern, repl_func, s]

Use it as follows:

>>> ReplWrapper[REPL_DICT].multiple_replace[s]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'

Thay thế nhiều mẫu trong một lần vượt qua

Tín dụng: Xavier DeFrang

Vấn đề

Bạn cần thực hiện một số thay thế chuỗi trên một chuỗi.

Dung dịch

Đôi khi các biểu thức thông thường đủ khả năng giải pháp nhanh nhất ngay cả trong trường hợp khả năng ứng dụng của chúng là bất cứ điều gì nhưng rõ ràng. Cụ thể, phương pháp

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
1 của các đối tượng
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
2 làm cho các biểu thức thường xuyên trở thành một cách tốt để thực hiện các thay thế chuỗi. Dưới đây là cách bạn có thể tạo ra một chuỗi kết quả từ một chuỗi đầu vào trong đó mỗi lần xuất hiện của bất kỳ khóa nào trong một từ điển nhất định được thay thế bằng giá trị tương ứng trong từ điển:

# requires Python 2.1 or later
from _ _future_ _ import nested_scopes

import re

# the simplest, lambda-based implementation
def multiple_replace[adict, text]:
  # Create a regular expression from all of the dictionary keys
  regex = re.compile["|".join[map[re.escape, adict.keys[  ]]]]

  # For each match, look up the corresponding value in the dictionary
  return regex.sub[lambda match: adict[match.group[0]], text]

Một cách tiếp cận mạnh mẽ và linh hoạt hơn là bọc từ điển thành một đối tượng có thể gọi được, hỗ trợ trực tiếp cho ý tưởng tra cứu và thay thế mà bạn có thể sử dụng trực tiếp làm gọi lại trong phương thức

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
1. Cách tiếp cận hướng đối tượng này linh hoạt hơn vì đối tượng có thể gọi có thể giữ trạng thái riêng của nó và do đó dễ dàng mở rộng cho các tác vụ khác. Trong Python 2.2 trở lên, bạn có thể tạo một lớp cho đối tượng này bằng cách mở rộng loại tích hợp
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
4, trong khi trong các phiên bản Python cũ hơn, bạn phải quay lại
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
5 [các loại tích hợp không thể phân biệt được trong các phiên bản cũ hơn]. A ________ 16/________ 17 Cho phép chúng tôi dễ dàng viết mã hoạt động tối ưu trên cả phiên bản cũ và mới của Python:

try: dict
except: from UserDict import UserDict as dict

class Xlator[dict]:
    """ All-in-one multiple-string-substitution class """
    def _make_regex[self]:
        """ Build re object based on the keys of the current dictionary """
        return re.compile["|".join[map[re.escape, self.keys[  ]]]]

    def _ _call_ _[self, match]:
        """ Handler invoked for each regex match """
        return self[match.group[0]]

    def xlat[self, text]:
        """ Translate text, returns the modified text. """
        return self._make_regex[  ].sub[self, text]

Thảo luận

Công thức này cho thấy cách sử dụng mô-đun

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
2 tiêu chuẩn Python để thực hiện thay thế nhiều chuỗi đơn bằng cách sử dụng từ điển. Hãy nói rằng bạn có một bản đồ một-một, dựa trên từ điển giữa các chuỗi. Các khóa là tập hợp các chuỗi [hoặc các mẫu biểu hiện thông thường] mà bạn muốn thay thế và các giá trị tương ứng là các chuỗi để thay thế chúng. Bạn có thể thực hiện thay thế bằng cách gọi
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
9 cho mỗi cặp khóa/giá trị trong từ điển, do đó xử lý và tạo một bản sao mới của toàn bộ văn bản nhiều lần, nhưng rõ ràng là tốt hơn là thực hiện tất cả các thay đổi trong một lần vượt qua, xử lý và tạo một bản sao của văn bản chỉ một lần. May mắn thay, cơ sở gọi lại ____ 19 làm cho cách tiếp cận tốt hơn này khá dễ dàng.

Đầu tiên, chúng ta phải xây dựng một biểu thức thông thường từ tập hợp các phím mà chúng ta muốn khớp. Một biểu thức thông thường như vậy là một mẫu của biểu mẫu A1 | A2 | ... | một "và có thể dễ dàng được tạo bằng cách sử dụng một lớp lót, như thể hiện trong công thức. với một đối số gọi lại.

s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
9 gọi đối tượng này cho mỗi trận đấu, với một
>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
3 là đối số duy nhất của nó và mong đợi chuỗi thay thế là kết quả của cuộc gọi. Trong trường hợp của chúng tôi, cuộc gọi lại chỉ cần tra cứu văn bản phù hợp trong từ điển và Trả về giá trị tương ứng.n" and can easily be generated using a one-liner, as shown in the recipe. Then, instead of giving
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
9 a replacement string, we call it with a callback argument.
s = 'This is a sample string. Which is getting replaced. 1234-5678.'

REPL_DICT = {
    r'[.*?]is[.*?]ing[.*?]ch': r'\3-\2-\1',
    r'replaced': 'REPLACED',
    r'\d\d[[\d][\d]-[\d][\d]]\d\d': r'__\5\4__\3\2__',
    r'get|ing': '!@#'
}
9 calls this object for each match, with a
>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
3 as its only argument, and expects the replacement string as the call’s result. In our case, the callback just has to look up the matched text in the dictionary and return the corresponding value.

Công thức có hai triển khai: một là dựa trên ____ 24 và cái còn lại sử dụng một đối tượng giống như từ điển có thể gọi được. Tùy chọn thứ hai tốt hơn nếu bạn muốn thực hiện xử lý bổ sung trên mỗi trận đấu [ví dụ: xây dựng biểu đồ số lần mỗi lần thay thế có thể được thực hiện] hoặc nếu bạn không thích

>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
4. Một lợi thế tiềm năng khác của phương pháp dựa trên lớp là hiệu suất. Nếu bạn biết rằng từ điển dịch là tĩnh và bạn phải áp dụng cùng một bản dịch cho một số chuỗi đầu vào, bạn có thể chuyển cuộc gọi
>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
6 từ phương thức
>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
7, nơi nó hiện đang được thực hiện, sang một phương thức
>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
8, để tránh nhiều lần chuẩn bị và biên dịch biểu hiện thông thường.

Ở đây, một ví dụ sử dụng cho mỗi nửa của công thức này. Thông thường chúng ta sẽ có nó như là một phần của cùng một tệp nguồn

>>> multiple_replace[s, REPL_DICT]
'. Whi- is a sample str-Th is !@#t!@# REPLACED. __65__43__.'
9 như hàm và lớp được hiển thị trong công thức, vì vậy nó được bảo vệ bởi thành ngữ Python truyền thống chạy nó khi và chỉ khi mô -đun được gọi là tập lệnh chính:

if _ _name_ _ == "_ _main_ _":
    text = "Larry Wall is the creator of Perl"
    adict = {
      "Larry Wall" : "Guido van Rossum",
      "creator" : "Benevolent Dictator for Life",
      "Perl" : "Python",
    }

    print multiple_replace[adict, text]

    xlat = Xlator[adict]
    print xlat.xlat[text]

Các thay thế như những gì được thực hiện bởi công thức này thường được dự định để hoạt động trên toàn bộ từ, thay vì trên các nền tảng tùy ý. Biểu thức chính quy rất giỏi trong việc chọn sự khởi đầu và kết thúc của các từ, nhờ vào chuỗi đặc biệt

import re
from itertools import islice

class ReplWrapper:
    def __init__[self, repl_dict]:
        self.repl_dict = repl_dict
        self.groups_no = [re.compile[pattern].groups for pattern in repl_dict]
        self.full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    def get_pattern_repl[self, pos]:
        return next[islice[self.repl_dict.items[], pos, pos + 1]]

    def multiple_replace[self, s]:
        def repl_func[m]:
            all_groups = m.groups[]

            # Use 'i' as the index within 'all_groups' and 'j' as the main
            # group index.
            i, j = 0, 0

            while i < len[all_groups] and all_groups[i] is None:
                # Skip the inner groups and move on to the next group.
                i += [self.groups_no[j] + 1]

                # Advance the main group index.
                j += 1

            return re.sub[*self.get_pattern_repl[j], all_groups[i]]

        return re.sub[self.full_pattern, repl_func, s]
0. Do đó, chúng ta có thể dễ dàng tạo một phiên bản của lớp
import re
from itertools import islice

class ReplWrapper:
    def __init__[self, repl_dict]:
        self.repl_dict = repl_dict
        self.groups_no = [re.compile[pattern].groups for pattern in repl_dict]
        self.full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    def get_pattern_repl[self, pos]:
        return next[islice[self.repl_dict.items[], pos, pos + 1]]

    def multiple_replace[self, s]:
        def repl_func[m]:
            all_groups = m.groups[]

            # Use 'i' as the index within 'all_groups' and 'j' as the main
            # group index.
            i, j = 0, 0

            while i < len[all_groups] and all_groups[i] is None:
                # Skip the inner groups and move on to the next group.
                i += [self.groups_no[j] + 1]

                # Advance the main group index.
                j += 1

            return re.sub[*self.get_pattern_repl[j], all_groups[i]]

        return re.sub[self.full_pattern, repl_func, s]
1 bị hạn chế chỉ thay thế toàn bộ từ:

class WordXlator[Xlator]:
    """ An Xlator version to substitute only entire words """
    def _make_regex[self]:
        return re.compile[
          r'\b'+r'\b|\b'.join[map[re.escape, self.keys[  ]]]+r'\b']

Lưu ý mức độ dễ dàng hơn khi tùy chỉnh

import re
from itertools import islice

class ReplWrapper:
    def __init__[self, repl_dict]:
        self.repl_dict = repl_dict
        self.groups_no = [re.compile[pattern].groups for pattern in repl_dict]
        self.full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    def get_pattern_repl[self, pos]:
        return next[islice[self.repl_dict.items[], pos, pos + 1]]

    def multiple_replace[self, s]:
        def repl_func[m]:
            all_groups = m.groups[]

            # Use 'i' as the index within 'all_groups' and 'j' as the main
            # group index.
            i, j = 0, 0

            while i < len[all_groups] and all_groups[i] is None:
                # Skip the inner groups and move on to the next group.
                i += [self.groups_no[j] + 1]

                # Advance the main group index.
                j += 1

            return re.sub[*self.get_pattern_repl[j], all_groups[i]]

        return re.sub[self.full_pattern, repl_func, s]
1 so với việc tùy chỉnh hàm
import re
from itertools import islice

class ReplWrapper:
    def __init__[self, repl_dict]:
        self.repl_dict = repl_dict
        self.groups_no = [re.compile[pattern].groups for pattern in repl_dict]
        self.full_pattern = '|'.join[f'[{pattern}]' for pattern in repl_dict]

    def get_pattern_repl[self, pos]:
        return next[islice[self.repl_dict.items[], pos, pos + 1]]

    def multiple_replace[self, s]:
        def repl_func[m]:
            all_groups = m.groups[]

            # Use 'i' as the index within 'all_groups' and 'j' as the main
            # group index.
            i, j = 0, 0

            while i < len[all_groups] and all_groups[i] is None:
                # Skip the inner groups and move on to the next group.
                i += [self.groups_no[j] + 1]

                # Advance the main group index.
                j += 1

            return re.sub[*self.get_pattern_repl[j], all_groups[i]]

        return re.sub[self.full_pattern, repl_func, s]
3. Dễ dàng tùy chỉnh bằng cách phân lớp và ghi đè giúp bạn tránh mã hóa sao chép và dán, và đây là một lý do tuyệt vời khác để thích các cấu trúc hướng đối tượng hơn các cấu trúc đơn giản hơn. Tất nhiên, chỉ vì một số chức năng được đóng gói như một lớp học không có thể tùy chỉnh theo cách bạn muốn. Khả năng tùy chỉnh cũng có một số tầm nhìn xa trong việc chia chức năng thành các phương pháp có thể ghi chép riêng biệt tương ứng với các phần phù hợp của chức năng tổng thể. May mắn thay, bạn không cần phải có được nó ngay lần đầu tiên; Khi mã không có cấu trúc nội bộ tối ưu cho nhiệm vụ trong tay [ví dụ: tái sử dụng bằng cách phân lớp và ghi đè có chọn lọc], bạn có thể và nên tái cấu trúc mã để cấu trúc bên trong của nó phục vụ nhu cầu của bạn. Chỉ cần đảm bảo rằng bạn có một pin kiểm tra phù hợp sẵn sàng để chạy để đảm bảo rằng việc tái cấu trúc của bạn đã bị hỏng bất cứ thứ gì, và sau đó bạn có thể tái cấu trúc nội dung trái tim của bạn. Xem //www.refactoring.com để biết thêm thông tin về nghệ thuật quan trọng và thực hành tái cấu trúc.

Nhận cuốn sách nấu ăn Python ngay bây giờ với nền tảng học tập O hèReilly.learning platform.

Các thành viên của O hèReilly trải nghiệm đào tạo trực tuyến trực tiếp, cộng với sách, video và nội dung kỹ thuật số từ gần 200 nhà xuất bản.nearly 200 publishers.

Làm thế nào để bạn thay thế nhiều mẫu trong Python?

subn [] để thay thế nhiều chuỗi con trong một chuỗi. sub [] - Nó thay thế nội dung của một chuỗi dựa trên các mẫu. Nó lấy một mẫu hoặc một chuỗi làm đối số đầu tiên. Đối số thứ hai là hàm LambDA trích xuất chuỗi con phù hợp sau đó trả về giá trị được liên kết với nó từ từ điển. to replace multiple substrings in a string. sub[] - It replaces the contents of a string based on patterns. It takes a pattern or a string as the first argument. The second argument is the lambda function which extracts the matched sub-string then returns the value associated with it from the dictionary.

Làm thế nào để bạn thay thế tất cả các lần xuất hiện của một mẫu regex trong một python chuỗi?

Phương thức Sub [] sẽ thay thế tất cả các lần xuất hiện trong chuỗi đích. will replace all pattern occurrences in the target string.

Làm thế nào để bạn thay thế một mẫu trong Python?

Để thay thế một chuỗi trong Python, phương thức Regex Sub [] được sử dụng.Đây là một phương thức Python tích hợp trong mô-đun RE trả về chuỗi thay thế.Đừng quên nhập mô -đun lại.Phương thức này tìm kiếm mẫu trong chuỗi và sau đó thay thế nó bằng một biểu thức mới được cho.the regex sub[] method is used. It is a built-in Python method in re module that returns replaced string. Don't forget to import the re module. This method searches the pattern in the string and then replace it with a new given expression.

RE SUB [] trong Python là gì?

lại.Hàm Sub [] được sử dụng để thay thế các lần xuất hiện của một chuỗi phụ cụ thể bằng một chuỗi phụ khác.Hàm này lấy đầu vào như sau: chuỗi phụ để thay thế.Chuỗi phụ để thay thế bằng.Chuỗi thực tế.used to replace occurrences of a particular sub-string with another sub-string. This function takes as input the following: The sub-string to replace. The sub-string to replace with. The actual string.

Bài Viết Liên Quan

Chủ Đề