【问题标题】:python regex error : TypeError: expected string or bytes-like objectpython 正则表达式错误:TypeError:预期的字符串或类似字节的对象
【发布时间】:2017-04-21 13:01:03
【问题描述】:

我有以下代码。

import datetime
import re


class Entry:
    task_name = None
    minutes = None
    notes = None
    created_at = None

    def __init__(self, task_name=None, minutes=None,
                 created_at=None, notes=None):
        if task_name:
            self.task_name = task_name
            self.minutes = int(minutes)
            self.created_at = datetime.datetime.strptime(
                                                    created_at,
                                                    "%Y-%m-%d %H:%M:%S.%f")
            self.notes = notes
        else:
            self.get_task_details()

    # get task name, num of minutes and notes if required
    def get_task_details(self):
        self.task_name = input("Enter the name of the task: ")
        self.minutes = self.get_minutes()
        self.notes = self.get_notes()
        self.created_at = datetime.datetime.now()

    # get num of minutes and verify it
    # the user should enter a valid input
    def get_minutes(self):
        while True:
            minutes = input("Enter the number of minutes spent on the task: ")
            if minutes:
                try:
                    minutes = int(minutes)
                    return minutes
                except ValueError:
                    print("Please Enter a valid num of minutes")
            else:
                print("Please enter a valid input. ex 12")

    # print task info
    def get_task_info(self):
        print("You created your task at")
        created_at_formatted = self.created_at.strftime("%m/%d/%Y %H:%M")
        print("{}".format(created_at_formatted))

    # get notes if the user wants to
    # else: leave it with a value of None
    def get_notes(self):
        answer = input("Do you want to write any note on this task ? N/y >>> ")
        if answer.lower() == "y":
            note = input("Enter your note >>> ")
            return note
        else:
            self.notes = None
            print("Alright. No notes are added")

    def __str__(self):
        return """
        Task Name: {}
        Created At: {}
        Minutes Spend: {}
        Notes: {}
        """.format(self.task_name, self.created_at, self.minutes, self.notes)

class Log:
    e = Entry()
    entries = []
    entries.append(e)

    def find_by_pattern(self):
        """find by regex pattern"""
        regex = input("Enter your regex >>> ")
        try:
            regex = re.compile(r'{}'.format(regex), re.X)
        except sre_constants.error:
            print("Invalid regex")
            regex = None
        entries_found = []
        # check if the user entered a regex
        if regex:
            for entry in self.entries:
                if (re.findall(regex, entry.task_name) or
                        re.findall(regex, entry.notes)):
                        entries_found.append(entry)
        else:
            print("Please enter a  valid regex")

        if entries_found:
            if entries_found:
                print("We found the following entries")
                for entry in entries_found:
                    print("{}".format(entry))
        else:
            print("No entries were found based on your pattern")

if __name__ == "__main__":
    l = Log()
    l.find_by_pattern()

当我运行程序并输入正则表达式时:'\w{4}';它崩溃了 但是,如果我运行程序并输入相同的正则表达式但不带引号:\w{r},它不会崩溃。 这是我正在尝试做的更清晰的图片:

【问题讨论】:

    标签: python regex


    【解决方案1】:

    这不是因为正则表达式而崩溃,而是因为entry.notesNonefindall 需要一个字符串。

    它在第一个示例中有效,因为正则表达式匹配 entry.task_name,因此条件行 88-89 的其他部分被跳过。
    但是,当输入引号时,正则表达式与第一部分不匹配(它需要引号)并在后者为 None 时崩溃。

    您可以通过输入注释来验证这一点,它不会崩溃,尽管将这些属性初始化为空字符串可能更明智。

    PS:请注意,在get_notes 中,如果有任何注释,您将返回该注释,但在其他情况下,您可能希望返回实际值(或者当函数返回并在第 27 行设置 None 时该值将被删除) )

    这是一个快速/修复不佳的版本:

    import datetime
    import re
    
    
    class Entry:
        task_name = ""
        minutes = None
        notes = ""
        created_at = None
    
        def __init__(self, task_name=None, minutes=None,
                     created_at=None, notes=""):
            if task_name:
                self.task_name = task_name
                self.minutes = int(minutes)
                self.created_at = datetime.datetime.strptime(
                                                        created_at,
                                                        "%Y-%m-%d %H:%M:%S.%f")
                self.notes = notes
            else:
                self.get_task_details()
    
        # get task name, num of minutes and notes if required
        def get_task_details(self):
            self.task_name = input("Enter the name of the task: ")
            self.minutes = self.get_minutes()
            self.notes = self.get_notes()
            self.created_at = datetime.datetime.now()
    
        # get num of minutes and verify it
        # the user should enter a valid input
        def get_minutes(self):
            while True:
                minutes = input("Enter the number of minutes spent on the task: ")
                if minutes:
                    try:
                        minutes = int(minutes)
                        return minutes
                    except ValueError:
                        print("Please Enter a valid num of minutes")
                else:
                    print("Please enter a valid input. ex 12")
    
        # print task info
        def get_task_info(self):
            print("You created your task at")
            created_at_formatted = self.created_at.strftime("%m/%d/%Y %H:%M")
            print("{}".format(created_at_formatted))
    
        # get notes if the user wants to
        # else: leave it with a value of None
        def get_notes(self):
            answer = input("Do you want to write any note on this task ? N/y >>> ")
            if answer.lower() == "y":
                note = input("Enter your note >>> ")
                return note
            else:
                return ""
                print("Alright. No notes are added")
    
        def __str__(self):
            return """
            Task Name: {}
            Created At: {}
            Minutes Spend: {}
            Notes: {}
            """.format(self.task_name, self.created_at, self.minutes, self.notes)
    
    class Log:
        e = Entry()
        entries = []
        entries.append(e)
    
        def find_by_pattern(self):
            """find by regex pattern"""
            regex = input("Enter your regex >>> ")
            try:
                regex = re.compile(r'{}'.format(regex), re.X)
            except sre_constants.error:
                print("Invalid regex")
                regex = None
            entries_found = []
            # check if the user entered a regex
            if regex:
                for entry in self.entries:
                    if (re.findall(regex, entry.task_name) or
                            re.findall(regex, entry.notes)):
                            entries_found.append(entry)
            else:
                print("Please enter a  valid regex")
    
            if entries_found:
                if entries_found:
                    print("We found the following entries")
                    for entry in entries_found:
                        print("{}".format(entry))
            else:
                print("No entries were found based on your pattern")
    
    if __name__ == "__main__":
        l = Log()
        l.find_by_pattern()
    

    【讨论】:

      【解决方案2】:

      根据错误:

      expected string or bytes-like object
      

      您只需要使用 str() 将后面的部分作为字符串类型的数据传输:

      if (re.findall(regex, str(entry.task_name)) or
                              re.findall(regex, str(entry.notes))):
                              entries_found.append(entry)
      

      或者你可以尝试在findall函数的第二个参数前面加上b'xxx'。不是变量,是原始字符串。

      【讨论】:

        猜你喜欢
        • 2020-10-20
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 2017-08-29
        • 1970-01-01
        • 2020-11-09
        • 2019-10-31
        • 1970-01-01
        相关资源
        最近更新 更多