【问题标题】:regex - find and replace and convert to csv format正则表达式 - 查找和替换并转换为 csv 格式
【发布时间】:2017-04-09 21:17:31
【问题描述】:

我有一个包含电话号码的文件,并想从中创建一个 csv 文件。

我面临的问题是格式不固定,不易解析。

  • 每行包含一个、两个或三个电话记录。
  • 一个电话可能以 (+xxx) 开头,也可能不以 (+xxx) 开头,第二个电话可能以“&”开头。

我试图构建一个 regex,它可以将每一行分成 3 组,然后查找/替换为预期的格式,但没有成功。

任何人都可以想出一个 regex 来识别每行的每个组吗?

输入

(+999) 11 762 52 61 (+999) 11 762 41 11
(+999) 44 695 01 76 & 44 695 01 89
(+999) 21 510 02 14 (+999) 21 511 97 98
(+999) 01 05 00 18 67
(+999) 21 552 42 12
(+999) 21 557 86 60 (+999) 21 557 86 72
(+999) 11 873 93 13 & 11 825 59 92
(+999) 15 307 57 15 & 15 307 57 16 & (+999) 11 974 19 57
(+999) 21 551 91 51 (+999) 21 551 91 68
(+999) 21 551 71 71 & 21 551 72 32
(+999) 21 527 30 00 (+999) 21 551 54 89
(+999) 11 621 15 00 (+999) 11 626 20 75
(+999) 21 555 21 60 (+999) 21 555 21 71 (+999) 12 804 76 30
(+999) 11 234 18 96 (+999) 11 234 54 48
(+999) 11 828 35 37 (+999) 11 828 63 76 (+999) 41 363 27 23
(+999) 11 690 03 00 (+999) 11 315 65 38
(+999) 08 32 60 34 65
(+999) 08 32 60 34 65 & (+999) 11 784 46 70 & (+999) 11 784 61 79

预期结果:

(+999) 11 762 52 61, (+999) 11 762 41 11,
(+999) 44 695 01 76, 44 695 01 89,
(+999) 21 510 02 14, (+999) 21 511 97 98,
(+999) 01 05 00 18 67,,
(+999) 21 552 42 12,,
(+999) 21 557 86 60, (+999) 21 557 86 72,
(+999) 11 873 93 13, 11 825 59 92,
(+999) 15 307 57 15, 15 307 57 16, (+999) 11 974 19 57
(+999) 21 551 91 51, (+999) 21 551 91 68,
(+999) 21 551 71 71, 21 551 72 32,
(+999) 21 527 30 00, (+999) 21 551 54 89,
(+999) 11 621 15 00, (+999) 11 626 20 75,
(+999) 21 555 21 60, (+999) 21 555 21 71, (+999) 12 804 76 30
(+999) 11 234 18 96, (+999) 11 234 54 48,
(+999) 11 828 35 37, (+999) 11 828 63 76, (+999) 41 363 27 23
(+999) 11 690 03 00, (+999) 11 315 65 38,
(+999) 08 32 60 34 65,,
(+999) 08 32 60 34 65, (+999) 11 784 46 70, (+999) 11 784 61 79

【问题讨论】:

  • 如果你用的是python --> 为什么不数一排数字的数量呢?
  • (& \(|[&(]+) 拆分/分解可能吗?

标签: python regex csv


【解决方案1】:
import math

for l in file: 

    nr_of_prefixes = l.count('(+')  # amount of prefixes (+xxx)
    prefixes = nr_of_prefixes * 3 # count the characters of a prefix
    numbers = sum(c.isdigit() for c in l) # amount of numbers in a string
    numbers -= prefixes # remove the prefixes
    telephone_numbers = math.floor(numbers / 8) # number of digits


    l = l.replace(' (+',', (+') # add a , to    (+
    l = l.replace(' &',',')     # replace a & by a comma
    l = l.replace(',,',',')     # replace double ,,  by a single  ,

    # if there where only 2 phone numbers, add an ending comma
    if telephone_numbers < 3:
        l += ","

    # if there was only 1 phone numbers, add an extra comma
    if telephone_numbers < 2:
        l += ","

    # print, or add to a list 
    print(l)

【讨论】:

  • 是的,太棒了!谢谢
【解决方案2】:

使用以下正则表达式:((\(\+999\)[\d ]+)|&amp; ([\d ]+))

这是一个包含您的文件内容的示例:

https://regex101.com/r/Q8grqd/1

以及regex101代码生成器生成的python代码

import re

regex = r"((\(\+999\)[\d ]+)|& ([\d ]+))"

test_str = ("(+999) 11 762 52 61 (+999) 11 762 41 11\n"
    "(+999) 44 695 01 76 & 44 695 01 89\n"
    "(+999) 21 510 02 14 (+999) 21 511 97 98\n"
    "(+999) 01 05 00 18 67\n"
    "(+999) 21 552 42 12\n"
    "(+999) 21 557 86 60 (+999) 21 557 86 72\n"
    "(+999) 11 873 93 13 & 11 825 59 92\n"
    "(+999) 15 307 57 15 & 15 307 57 16 & (+999) 11 974 19 57\n"
    "(+999) 21 551 91 51 (+999) 21 551 91 68\n"
    "(+999) 21 551 71 71 & 21 551 72 32\n"
    "(+999) 21 527 30 00 (+999) 21 551 54 89\n"
    "(+999) 11 621 15 00 (+999) 11 626 20 75\n"
    "(+999) 21 555 21 60 (+999) 21 555 21 71 (+999) 12 804 76 30\n"
    "(+999) 11 234 18 96 (+999) 11 234 54 48\n"
    "(+999) 11 828 35 37 (+999) 11 828 63 76 (+999) 41 363 27 23\n"
    "(+999) 11 690 03 00 (+999) 11 315 65 38\n"
    "(+999) 08 32 60 34 65\n"
    "(+999) 08 32 60 34 65 & (+999) 11 784 46 70 & (+999) 11 784 61 79")

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches):
    matchNum = matchNum + 1

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

【讨论】:

  • 这已经是一些东西了,但并不完全正确。它重复匹配并且远离所需的输出。但无论如何谢谢:)
  • 我提供了正则表达式来提取每一行的电话号码,这不是你想要的吗?,对不起,我知道正则表达式,而不是 python,代码是从正则表达式 101 生成的,我以为你知道如何使用它;)
  • 正则表达式似乎不能提供我正在寻找的东西,例如,如果您使用记事本++、pycharm 等编辑器并将其用于查找/替换(作为正则表达式)并替换为 3 grpups (\1,\2,\3) 不适用于所有情况
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 2012-06-06
  • 2015-03-25
  • 2011-06-16
  • 1970-01-01
  • 2017-01-28
相关资源
最近更新 更多