【问题标题】:Regular Expression Vs. String Parsing正则表达式与。字符串解析
【发布时间】:2012-08-07 23:34:48
【问题描述】:

冒着打开一罐蠕虫并获得反对票的风险,我发现自己需要问,

什么时候应该使用正则表达式,什么时候使用字符串解析更合适?

我需要例子推理来说明你的立场。我希望您解决诸如可读性可维护性可扩展性,以及可能最重要的性能你的答案。

我发现了另一个问题Here,它只有 1 个答案,甚至连举个例子都麻烦。我需要更多了解这一点。

我目前正在使用 C++,但正则表达式几乎出现在所有高级语言中,我也想知道不同的语言如何使用/处理正则表达式,但这更多是事后的想法。

感谢您的帮助!

编辑:我仍在寻找更多示例并就此进行讨论,但迄今为止的反应非常好。 :)

【问题讨论】:

标签: regex string performance parsing language-agnostic


【解决方案1】:

这取决于您处理的语言有多复杂。

拆分

这很好用,但只有在没有转义约定时才有效。 例如,它不适用于 CSV,因为带引号的字符串中的逗号不是正确的分割点。

foo,bar,baz

可以拆分,但是

foo,"bar,baz"

不能。

常规

正则表达式非常适合具有"regular grammar" 的简单语言。由于反向引用,Perl 5 正则表达式更强大一些,但一般的经验法则是:

如果您需要匹配括号((...)[...])或其他嵌套如 HTML 标记,那么仅靠正则表达式是不够的。

您可以使用正则表达式将字符串分解为已知数量的块——例如,从日期中提取月/日/年。但是,它们不适合解析复杂的算术表达式。

很明显,如果你写了一个正则表达式,走开喝杯咖啡,回来,并且不能轻易理解你刚刚写的东西,那么你应该寻找一种更清晰的方式来表达你正在做的事情。 Email addresses 可能处于使用正则表达式可以正确且可读地处理的极限。

上下文无关

解析器生成器和手动编码的下推/PEG 解析器非常适合处理需要处理 嵌套 的更复杂的输入,因此您可以构建 或处理operator precedence 或关联性。

上下文无关解析器通常使用正则表达式首先将输入分解为块(空格、标识符、标点符号、带引号的字符串),然后使用语法将该块流转换为树形。

CF 语法的经验法则是

如果正则表达式不充分,但语言中的所有单词都具有相同的含义,而不管先前的声明如何,则 CF 有效。

非上下文无关

如果您的语言中的单词会根据上下文改变含义,那么您需要一个更复杂的解决方案。这些几乎都是手工编码的解决方案。

例如,在 C 语言中,

#ifdef X
  typedef int foo
#endif

foo * bar

如果foo 是一个类型,那么foo * bar 是一个名为barfoo 指针的声明。否则,它是一个名为 foo 的变量乘以一个名为 bar 的变量。

【讨论】:

  • 有趣的是,您应该提到 CSV 文件。它们是让我想问这个问题的原因之一。当我说在处理 CSV 文件时应该使用字符串解析器而不是正则表达式时,我是否正确地解释了你的示例?
  • @Dan,正则表达式可以很好地处理 CSV 文件——没有任意深度的嵌套,只有两级深度结构。对于 IE 风格,您可以使用 /([^\r\n"]|"(?:[^"]|"")*")/g 之类的东西找到行,它允许在使用双引号对转义双引号的带引号的字符串中换行。然后,您可以使用/([^,"]|"(?:[^"]|"")*")*/g 之类的方式在一行中查找字段。然后,您只需要使用 /"(?:[^"]|"")*"/ 查找引用的部分,去掉外部引号并将所有出现的 "" 替换为 "
  • 多年前的问题,但我想评论一下,CSV 通常应该由解析器处理,而不是正则表达式。事实上,在 csv 解析中有很多意想不到的陷阱和陷阱,你甚至应该使用成熟的库来完成任务,而不是自制的解决方案。 (除非您在自定义应用程序中端到端控制 csv。)
  • @MikeSamuel - “电子邮件地址可能是使用正则表达式可以正确且可读地处理的极限。”荒谬。正则表达式确实是一门独立的语言,需要很好地理解,但这并不意味着我们应该编写大量的程序代码来解析字符串,因为我们只是不理解。知道你在用 regex 做什么会让任何代码的可维护性和可读性大不相同。正则表达式很复杂,但非常标准化。程序解析代码容易出错且费力。
  • @JoeyCarson,您似乎想反驳您引用的内容。我断言(1)正则表达式和过程代码之间没有二分法,(2)我从未声称不需要知道正则表达式,并且引用的文本并不暗示这一点,以及(3)熟悉正则表达式语法并不帮助制定一个简单的正则表达式解决方案来处理电子邮件——emailregex.com 既不小也不简单也不可读。如果您认为正则表达式是比 CF 语法和代码更好的电子邮件处理工具,请提供证据。指向网络邮件系统中的正则表达式的指针会很好。
【解决方案2】:

应该是正则表达式AND字符串解析..

您可以同时使用它们来发挥自己的优势!很多时候,程序员尝试使用 SINGLE 正则表达式来解析文本,然后发现它很难维护。您应该在需要时同时使用它们。

REGEX 引擎是FAST。简单的匹配不到一微秒。但不推荐用于解析 HTML。

【讨论】:

  • You should use both as and when required. 什么时候?我需要一个例子。我的意思是你说的有道理,但我需要解释一下你的意思。
  • @Dan,请参阅我对常见案例的回答。解析 CF 语言时,通常使用正则表达式将其拆分为标记,然后使用完整解析器处理该标记流。例如,您可以将"(a + b)*c" 分解为["(", " ", "a", "+", " ", "b", ")", "*", "c"],然后丢弃空格并将结果提供给解析器以处理括号和运算符优先级以生成类似(Times (Plus (Var "a") (Var "b")) (Var "c")) 的树。
猜你喜欢
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
相关资源
最近更新 更多