【问题标题】:Should I use Regex to parse my file, or is there a better way? [closed]我应该使用正则表达式来解析我的文件,还是有更好的方法? [关闭]
【发布时间】:2011-12-09 08:56:58
【问题描述】:

我有一个超过 2000 行的文件需要解析。我想确保获得 100% 准确的结果,然后将其导入我的 MariaDB。

文件如下所示:

line 0: #start#
line 1: 20111211\200000
line 2: n=john|l=smith,131_stree_apt#102_city_state_11111_country,19989989988|17771112222,user%64domain.com,12,21,551|626|23\r
...
line 2156: #end#

所以 第 1 行是 24 小时格式的日期时间 第2行是行格式:

  • n = 名称
  • l = 姓氏
  • 完整地址
  • 手机+手机
  • 电子邮件
  • 总目标
  • 总传球次数
  • 冰上时间 + 板凳时间
  • 处罚分钟

我无法弄清楚正则表达式。我的另一个想法是解析每一行,然后解析每个逗号,然后解析每个管道等,但我认为这种方法比正则表达式慢且不准确。我说的对吗?

【问题讨论】:

  • “我认为它比正则表达式慢且不准确”---如果你还没有制作任何一个实现,你怎么能比较它们呢?
  • @zerkms 对不起,如果我没有你那么聪明,我只是想理解并尽可能地使我的代码变得更好
  • 学习是一个迭代过程。所以从你可以实现的东西开始,然后向我们展示要审查的结果(甚至还有一个stackexchange:codereview.stackexchange.com
  • 当然,explode 方法比特定的验证正则表达式更脆弱。 -- 你试过什么正则表达式?哪里失败了?
  • @XinQianChang'ang 让你的代码“尽可能好”的部分过程是通过构建一个使用定界符的解析器和一个使用正则表达式的解析器并比较结果来探索这样的案例。如果您还没有比较这两种情况,您的“我认为正则表达式更快、更准确”理论的基础是什么?

标签: php regex mariadb


【解决方案1】:

我无法弄清楚正则表达式,所以我的想法是先解析每一行,然后解析每个逗号,然后再解析每个管道……我认为这比正则表达式慢且不准确

你为什么不去试试呢? 不要让这个intimedate你,大胆点。 一般来说,如果我是你,我会做以下事情:

  1. 做一个简单的实现
  2. 测试一下
  3. 调整它

~2000 条记录并不多,因此甚至可能不需要第三步(特别是如果这是一次只运行一次的迁移——那如果需要 2 分钟呢?)。

顺便说一句:这是一般的编程建议,确实适用于很多问题。 Don't optimize prematurely.

【讨论】:

  • +1 如果您完全理解格式并编写正确的代码,它将与正则表达式一样准确。至于速度,我认为您必须非常努力地编写一个实现 2000 条记录所需时间超过几秒的实现。
【解决方案2】:

编写一个解析器,它们比正则表达式更强大,并且更容易编写和推理。

逐个字符读取文件,为每个字符决定你想用它做什么。

最初您正在阅读“日期”,然后当您找到换行符时,您就知道您已经完成了对日期的解析。

然后你解析每条记录。首先你希望看到n,继续阅读直到你得到|,然后你希望看到l,继续阅读直到你找到,,等等。 如果你发现了一些你没想到的东西,你就会知道解析器中存在错误,或者数据文件中存在错误。

你永远不会知道你是否完美地阅读了文件,没有 100%。只有“足够好”。 这是计算机科学的一般规律

【讨论】:

  • 除此之外 - 我想说解析器通常被称为Finite State Automate
  • 是的,但我觉得在这种情况下添加行话并没有帮助;)
  • 好吧,但它可能会帮助其他人找到你的答案。所以感谢@zerkms 为孩子命名;)。
【解决方案3】:

显然我不会给你完整的代码。但作为占位符回答并展示基本方法:

preg_match('/
   ^
     n=(\w+)       # just alphanumerics
     \|
     l=(\w+)
     ,
     ([\w\h\#]+)    # mixture of letters and space and #
     ,
     ([^,]*)       # anything but commas
     ...
   $
  /x', $line, $match);

它只需要与伪 CSV 行中的字段一样多的字符类和捕获组。 \d+ 仅匹配小数也可能有用。

在这里使用基本的字符串函数来编写一个假解析器显然是不明智的,因为正则表达式可以用更少的代码更可靠地做到这一点。

【讨论】:

  • 不过,这并没有让人觉得 OP 知道他的正则表达式。所以这可能是一个越差越好的情况。
  • 验证仍然是最好的技术方法,即使不适合 OP 经验。
  • 我没有质疑,我 +1d。
猜你喜欢
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
相关资源
最近更新 更多