【问题标题】:python reg ex to include missing commaspython 正则表达式包含缺少的逗号
【发布时间】:2015-09-07 06:50:49
【问题描述】:

我需要确保字符串具有逗号分隔值。我读的字符串可能有空格分隔的值。

  • 我的输入字符串中可能缺少一些逗号,也就是说,如果存在任何没有逗号的空格分隔值,我必须包含一个逗号
  • 我不应该对单引号或双引号内的字符串进行任何更改。这些带引号的值可以包含除引号之外的任何字母数字。

一个示例字符串是:

""" 1, ' unchanged 1' " unchanged  2 "  2.009, -2e15 """

我应该在“not this1”和“not this 2”之后加上逗号。

所以我的结果字符串应该是:

"""1,' unchanged 1'," unchanged 2 ",2.009,-2e15"""

我一直在尝试s1|s2|(s3) 类型的正则表达式。但未能完成任务。

字符串可以有不同数量的值以逗号分隔。

【问题讨论】:

  • 你的意思是像(re.sub(r"([\'\"].*?[\'\"])\s", r"\1, ",s)这样的吗?
  • 不同的字符串可以有不同数量的值以逗号分隔。例如。如果我将字符串更改为 """ 1, ' changed 1' " changed 2 " 2, 2 45""" 帕德莱克的 re 似乎不起作用。
  • PyParsing 可能是一种更易读的方法,如果这是一个选项...?
  • 我将从一个文件中读取这些行,该文件的行数在几十到大约 100k 之间。如果 PyParsing 不会显着使我的整个过程变慢,那么它是我的一个选择。
  • """ 1, ' unchanged 1' " unchanged 2 " 2, 2 45""" 应该输出什么?

标签: python regex python-2.7


【解决方案1】:

也许使用 findall、str.join 和 str.strip 会更容易,先查找引号之间的字符串,然后查找所有非空格:

s = """ 1, ' unchanged 1' " unchanged  2 "  2.009, -2e15 3"""

r = re.compile("[\'\"].*?[\'\"]|\S+")
print(", ".join([x.strip(",") for x in r.findall(s)]))

1, ' unchanged 1', " unchanged  2 ", 2.009, -2e11, ' unchanged 1', " unchanged  2 ", 2.009, -2e15, 35, 3

如果您不希望逗号后有任何空格:

print(",".join([x.strip(",") for x in r.findall(s)]))
1,' unchanged 1'," unchanged  2 ",2.009,-2e15,3

【讨论】:

  • 提出了附加要求:逗号分隔值之间可能没有空格。等式。我的示例字符串可以是 """ 1,' changed 1' " changed 2 " 2.009, -2e15 """ (第一个 1 和逗号之间没有空格)。可能有多个逗号分隔的值在一起,逗号前后没有任何空格。
  • 但是,两个非逗号分隔值之间会有一个或多个空格。
  • 此外,引号或双引号字符串中可以有逗号。但那些不应该改变。例如。 """667000, ,"0 2",100.0 ' space ', ,10""" 应该返回我 """667000, ,"0 2",100.0,' space ', ,10""" .
  • 等我回到我的笔记本电脑上去看看
  • Padraic:只要你有时间
【解决方案2】:

PyParsing 肯定不会是运行它的最快方式,但它可能是编写它的最快方式 ;-)

from pyparsing import *

STRING = sglQuotedString | dblQuotedString
NONSTRING = Word(alphanums + '.-')
line = OneOrMore(STRING | NONSTRING | Suppress(',')) + lineEnd


def insert_commas(s):
    values = line.parseString(s).asList()
    return ", ".join(values)


s1 = """1, ' unchanged 1' " unchanged  2 "  2, 2"""
s2 = """1, ' unchanged 1', " unchanged 2 " ,  2, 2"""
s3 = """ 1, ' unchanged 1' " unchanged 2 " 2, 2 45"""
s4 = """1, 67.90e-34 67.90E-34 7.9093339333 2, 2 """

print insert_commas(s1)
print insert_commas(s2)
print insert_commas(s3)
print insert_commas(s4)

打印出来的

1, ' unchanged 1', " unchanged  2 ", 2, 2
1, ' unchanged 1', " unchanged 2 ", 2, 2
1, ' unchanged 1', " unchanged 2 ", 2, 2, 45
1, 67.90e-34, 67.90E-34, 7.9093339333, 2, 2

【讨论】:

  • 感谢您提出解决方案。我不得不说这里的数字可以是浮点数。例如。 """1, 67.90e-34 67.90E-34 7.9093339333 2, 2 """.
  • 明天我会检查时间消耗方面的表现。我目前无法访问大文件。
  • 感谢比约恩。让我看看明天的表现,然后告诉你。
  • fwiw,我在一个不错的 i7 上获得了 5185 行/秒(不包括解析之外的任何内容),而 @Padraic Cunningham 的正则表达式解决方案为 185430 行/秒——他的版本不能处理缺失的空格虽然 """ 1' 不变 1'" 不变 2 "2, 2 45""" ;-)
  • thebjorn:在这种情况下,两个值之间不会有空格。如果是这样,我将不得不使用这种方法。非常感谢您为我评估性能。由于速度和当前范围,我想我会选择 Padraic 的解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-12-29
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多