Codewars--Phone Directory

本文介绍如何帮助John解析他的电话簿文本文件,该文件包含混乱的联系人信息。通过使用Python的正则表达式,从输入的字符串中提取电话号码、名字和地址,然后返回匹配的联系人详情。如果一个电话号码对应多人,返回"Too many people"错误,如果未找到号码,则返回"Not found"错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Phone Directory

Finally, I got it!

Problem Description:

John keeps a backup of his old personal phone book as a text file. On each line of the file he can find the phone number (formated as +X-abc-def-ghij where X stands for one or two digits), the corresponding name between < and > and the address.

Unfortunately everything is mixed, things are not always in the same order, lines are cluttered with non-alpha-numeric characters.

Examples of John’s phone book lines:

“/+1-541-754-3010 156 Alphand_St. \n”

" 133, Green, Rd. NY-56423 ;+1-541-914-3010!\n"

" +48-421-674-8974 Via Quirinal Roma\n"

Could you help John with a program that, given the lines of his phone book and a phone number returns a string for this number : “Phone => num, Name => name, Address => adress”

Examples:

s = “/+1-541-754-3010 156 Alphand_St. \n 133, Green, Rd. NY-56423 ;+1-541-914-3010!\n”

phone(s, “1-541-754-3010”) should return “Phone => 1-541-754-3010, Name => J Steeve, Address => 156 Alphand St.”

It can happen that, for a few phone numbers, there are many people for a phone number -say nb- , then

return : “Error => Too many people: nb”

or it can happen that the number nb is not in the phone book, in that case

return: “Error => Not found: nb”

You can see other examples in the test cases.

JavaScript random tests completed by @matt c
Note

Codewars stdout doesn’t print part of a string when between < and >

在这里插入图片描述

Click to get the problem description.


Version of Python:

在这里插入图片描述

Solution:

Method1:

# http://funhacks.net/2016/12/27/regular_expression/
import re
def phone(strng,num):
    lines = []
    lines = strng.split('\n')
    #print(lines)
    lists = []
    count = 0
    
    
    for i in range(len(lines)-1):
        pattern1=re.compile('.\d\-\d\d\d\-\d\d\d\-\d\d\d\d')
        Phone1=pattern1.findall(lines[i])
        Phone2=re.sub('[\+]','',Phone1[0])
        #print(Phone2)
        

        pattern2=re.compile('\<.*\>')
        Name1=pattern2.findall(lines[i])
        #print(Name1[0])
        

        Address1=re.sub('[\/\,\+\;\*]','',lines[i])
        Address2=Address1.replace(Phone2,'')
        Address3=Address2.replace(Name1[0],'').strip()
        Address4=re.sub('[\_\$\!\?\:]',' ',Address3)
        #print(Address4)
        Address4=Address4.split()
        #print(Address4)
        Address5=" ".join(Address4)
        #print(Address5)
        
        str1 = Phone2+'/'+Name1[0]+'/'+Address5
        #print(str1)
        
        lists.append(str1.split("/"))
        #print(lists)
        
    for i in range(len(lists)):
        if num == lists[i][0]:
            count += 1
    if count == 0:
        str2 = "Error => Not found: "+num
        return str2
    elif count == 1:
        for i in range(len(lists)):
            if num == lists[i][0]:
                Name2 = re.sub('[\<\>]','',lists[i][1])
                str3 = "Phone => "+lists[i][0]+", Name => "+Name2+", Address => "+lists[i][2]
        return str3
    else:
        str4 = "Error => Too many people: "+num
        return str4
Running:

在这里插入图片描述

在这里插入图片描述

Method2:

from re import sub

def phone(dir, num):
    if dir.count("+" + num) == 0:
        return "Error => Not found: " + num
    
    if dir.count("+" + num) > 1:
        return "Error => Too many people: " + num
    
    for line in dir.splitlines():
        if "+" + num in line:
            name = sub(".*<(.*)>.*", "\g<1>", line)
            line = sub("<" + name + ">|\+" + num, "", line)
            address = " ".join(sub("[^a-zA-Z0-9\.-]", " ", line).split())
            return "Phone => %s, Name => %s, Address => %s" % (num, name, address)

Method3:

import re

# Create the directory Phonebook
class Phonebook(object):
    def __init__(self):
        self.people = []


    def add_person(self, person):
        self.people.append(person)

    def __iter__(self):
        for elem in self.people:
            yield elem

    def find_phone(self, phone ):
        found = []
        for person in self.people:
            if str(person.phone) == str(phone):
                found.append(person)
        return found


# This is what will be stored in the phonebook:
class Person(object):
    def __init__(self, name, phone=None, address=None):
        self.name = name
        self.phone = phone
        self.address = address

    def add_phone(self, number):
        self.phone = number

    def add_address(self, address):
        self.address = address

    def show(self):
        print("Data:")
        s = 'name: %s \n' % self.name
        if self.phone is not None:
            s += 'general phone:   %s\n' % self.phone
        if self.address is not None:
            s += 'address address:  %s\n' % self.address
        print (s)




def phone(strng, num):
    phonebook = Phonebook()
# Working with the given data:
    datas = strng.split("\n")
    datas = [data for data in datas if data]
# Clean each line:
    for data in datas: # Not as clean as I would like:
        tel = re.findall("([1-9]*[1-9]-[0-9]\d{2}-[0-9]\d{2}-[0-9]\d{3})", data)[0]
        name = re.findall("(?<=\<)(.*?)(?=\>)", data)[0]
        address = data.replace(tel,"") # I bet there are better ways!!
        address = address.replace("<" + name + ">", "")
        address = re.sub('[^A-Za-z0-9-" ."]+', ' ', address)
        address = " ".join(address.split())
    # Now with the data clean, add it to a person:
        person = Person(name=name, phone=tel, address=address)
    # And add the person to phonebook
        phonebook.add_person(person)
    # Find the person by the Phone:
    results = phonebook.find_phone(num)
    if len(results) == 1:
        return ("Phone => {}, Name => {}, Address => {}".format(results[0].phone, results[0].name, results[0].address))
    if len(results) > 1:
        return "Error => Too many people: {}".format(num)
    if len(results) == 0:
        return "Error => Not found: {}".format(num)

Grammar Explanation(Method1):

  • pattern1=re.compile('.\d\-\d\d\d\-\d\d\d\-\d\d\d\d')
    Regular expression, in the page, the usage of regular expressions is described in detail. I am very grateful to the author for his help.
  1. In regular expression, it uses ".* " to represent a string of arbitrary length.
  2. The output of findall() function is a list. Both outputs of sub() and replace() are string.
  3. The append() function is based on list, in another way, it must to be used to handle list.3. The append() function is based on list, in another way, it must to be used to handle list.
  • lines = strng.split('\n')
    Click here to learn split() fuction.In conclusion, the output of this function is a list.
  • Address5=" ".join(Address4)
    Give some codes to show the usage of join() function.
## str >>>list 

str1 = "12345"
list1 = list(str1)
print list1
['1', '2', '3', '4', '5']
 
str2 = "123 sjhid dhi"
list2 = str2.split() #or list2 = str2.split(" ")
print list2
['123', 'sjhid', 'dhi']
 
str3 = "www.google.com"
list3 = str3.split(".")
print list3
['www', 'google', 'com']


##  list>>>str

str4 = "".join(list3)
print str4
wwwgooglecom

str5 = ".".join(list3)
print str5
www.google.com

str6 = " ".join(list3)
print str6
www google com

Also, you can refer to this page list>>>str and list—str .

It’s not easy for me to finish this problem. Write a blog to record it.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值