Bạn có thể thay thế nhiều thứ cùng một lúc trong Python không?

Đôi khi các biểu thức chính quy cung cấp 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à không rõ ràng. Đặc biệt, phương pháp sub của đối tượng re làm cho các biểu thức chính quy trở thành một cách tốt để thực hiện thay thế chuỗi. Đây là cách bạn có thể tạo chuỗi kết quả 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 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 ý tưởng tra cứu và thay thế mà bạn có thể sử dụng trực tiếp làm hàm gọi lại trong phương thức sub. 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 có thể giữ trạng thái của chính nó và do đó có thể 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 dựng sẵn dict, trong khi ở các phiên bản Python cũ hơn, bạn phải quay lại UserDict.UserDict (các loại dựng sẵn không thể phân lớp con trong các phiên bản cũ hơn). Một try/_______1_______0 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)

Công thức này cho thấy cách sử dụng mô-đun re tiêu chuẩn của Python để thực hiện thay thế nhiều chuỗi một lần bằng cách sử dụng từ điển. Giả sử bạn có ánh xạ một đối 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 mẫu biểu thức chính quy) 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

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)
2 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 tốt hơn là thực hiện tất cả các thay đổi trong một lượt, xử lý và tạo . May mắn thay, cơ sở gọi lại của
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)
2 làm cho cách tiếp cận tốt hơn này trở nên khá dễ dàng

Đầu tiên, chúng ta phải xây dựng một biểu thức chính quy từ tập hợp các khóa mà chúng ta muốn so khớp. Một biểu thức chính quy như vậy là một mẫu có dạng “a1. a2. an" và có thể dễ dàng được tạo bằng cách sử dụng một lớp lót, như được hiển thị trong công thức. Sau đó, thay vì cung cấp cho

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)
2 một chuỗi thay thế, chúng tôi gọi nó bằng một đối số gọi lại.
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)
2 gọi đối tượng này cho mỗi trận đấu, với _____1_______6 làm đố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

Công thức có hai cách thực hiện. một cái dựa trên

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)
7 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 sẽ 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 (e. g. , xây dựng một biểu đồ về số lần mỗi lần thay người có thể thực sự được thực hiện) hoặc nếu bạn không thích
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)
7. Một lợi thế tiềm năng khác của cách tiếp cận 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ể di chuyển lệnh gọi
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)
9 từ phương thức
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)
0, nơi nó hiện đang được thực hiện, sang phương thức
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)
1, để tránh phải chuẩn bị và biên dịch nhiều lần

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

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)
2 như chức năng và lớp được hiển thị trong công thức, do đó, 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 thay thế được thực hiện bởi công thức này thường nhằm mục đích hoạt động trên toàn bộ từ, thay vì trên các chuỗi con tùy ý. Cụm từ thông dụng rất tốt trong việc chọn phần đầu và phần cuối của từ, nhờ trình tự đặc biệt

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)
3. Do đó, chúng ta có thể dễ dàng tạo một phiên bản của lớp
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)
4 bị ràng buộc 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 ý rằng việc tùy 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)
4 dễ dàng hơn nhiều so với việc tùy chỉnh chức năng
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)
6. 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 theo thủ tục đơn giản hơn. Tất nhiên, chỉ vì một số chức năng được đóng gói thành một lớp không có nghĩa là nó có thể tùy chỉnh theo cách bạn muốn một cách kỳ diệu. Khả năng tùy chỉnh cũng cần một số tầm nhìn xa trong việc phân chia chức năng thành các phương thức có thể ghi đè 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 làm đúng ngay từ lần đầu tiên; . g. , tái sử dụng bằng cách phân lớp con và ghi đè có chọn lọc), bạn có thể và nên cấu trúc lại 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 lượng thử nghiệm phù hợp sẵn sàng chạy để đảm bảo rằng quá trình tái cấu trúc của bạn không làm hỏng bất kỳ thứ gì, và sau đó bạn có thể tái cấu trúc theo ý muốn của mình. xem http. //www. tái cấu trúc. 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