【问题标题】:Splitting line with escaped separators in Python在 Python 中使用转义分隔符分割线
【发布时间】:2016-08-01 13:08:02
【问题描述】:

TL;博士:

line = "one|two|three\|four\|five"
fields = line.split(whatever)

whatever 的值是什么:

fields == ['one', 'two', 'three\|four\|five']

我有一个由竖线字符分隔的文件。该文件中的一些字段还包括管道,由前导反斜杠转义。

例如,此文件中的单行数据可能具有['one', 'two', 'three\|four\|five'] 的数组表示,这将在文件中表示为one|two|three\|four\|five

我无法控制文件。我无法预处理文件。我必须一次性完成。

我最终需要将此文件的每一行拆分为单独的字段,但事实证明,前导反斜杠是各种麻烦。我最初尝试使用否定的前瞻,但在 python 字符串和双转义字符周围有某种我不理解的奥秘,这让我无法弄清楚。

对解决方案的解释表示赞赏,但可选。

【问题讨论】:

  • 编写你自己的解析器来解释转义序列,Python re 中的正则表达式无法处理它。
  • 你能澄清一下你的最终预期输出是什么吗? ['one', 'two', 'three\|four\|five']['one', 'two', 'three', 'four', 'five'] ?
  • @spasic:前者。

标签: python regex split negative-lookahead


【解决方案1】:

你可以使用像这样的正则表达式

re.split(r'([^|]+[^\\])\|', line)

它将使用字符组来指定除\ 之外的任何内容,然后使用| 进行拆分

这将在列表的开头给出一个额外的空匹配,但希望你可以像这样解决这个问题

re.split(r'([^|]+[^\\])\|', line)[1:]

当然,这仍然受制于 Wiktor 提出的解析问题

【讨论】:

  • 'one\\|two' 怎么样?它应该是not matched。当你有转义序列时,正则表达式永远不会准确。
  • 好点肯定,但如果出于某种原因要求使用split,这可能会尽可能接近
  • 我实际上并不介意 @WiktorStribiżewc 的边缘情况不满足。我不需要转义转义字符。我只需要拆分以不将r'\|' 识别为分隔符。您(@EricRenouf 的)提出的解决方案将不起作用,因为天真的拆分也将匹配先前字段中的最后一个字符,因此您最终得到 ['on', 'tw', 'three\\|four\\|five']。我在非捕获组和负前瞻中都试过这个,但前者无论如何都会捕获它,而后者什么都没有捕获。
  • @RHill 啊,哎呀,我撤回了我的建议!
  • @RHill 我刚刚更新了它,希望能解决最后一个字母被抓取的问题,尽管我还没有考虑过pandas 的要求
【解决方案2】:

也许你可以使用这样的东西:

[^\\]\|

其中[^\\] 匹配任何不同于\ 的字符。

【讨论】:

  • 不,这需要解析器。 'one\\|two' 呢?它应该是not matched
猜你喜欢
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-25
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
相关资源
最近更新 更多