Regex 正则表达式与字符串解析

Regex 正则表达式与字符串解析,regex,string,performance,parsing,language-agnostic,Regex,String,Performance,Parsing,Language Agnostic,冒着打开一罐蠕虫并获得反对票的风险,我发现自己需要问一下 什么时候应该使用正则表达式,什么时候更适合使用字符串解析? 关于你的立场,我需要例子和推理。我希望您在回答中说明可读性、可维护性、可伸缩性等问题,最重要的可能是性能 我发现另一个问题只有一个答案,甚至连举个例子都费劲。我需要更多的了解这一点 我现在在C++中玩,但是正则表达式几乎在所有高级语言中,我想知道不同的语言如何使用/处理正则表达式,但这是一个事后的想法。p> 谢谢你帮助我理解它 编辑:我仍在寻找更多的例子,并就此进行讨论,但到目前

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

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

关于你的立场,我需要例子和推理。我希望您在回答中说明可读性、可维护性、可伸缩性等问题,最重要的可能是性能

我发现另一个问题只有一个答案,甚至连举个例子都费劲。我需要更多的了解这一点

我现在在C++中玩,但是正则表达式几乎在所有高级语言中,我想知道不同的语言如何使用/处理正则表达式,但这是一个事后的想法。p> 谢谢你帮助我理解它


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

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

你可以利用这两个优势!很多时候程序员试图用一个正则表达式来解析一个文本,然后发现很难维护。您应该在需要时使用这两个正则表达式


正则表达式引擎速度很快。一个简单的匹配只需要不到一微秒的时间。但不建议将其用于解析HTML。

这取决于您所使用的语言有多复杂

分裂 这在起作用时非常好,但仅在存在无转义约定时才起作用。 例如,它不适用于CSV,因为带引号的字符串中的逗号不是正确的拆分点

福、巴、巴

可以拆分,但是

富,“酒吧,巴兹”

不能

有规律的 正则表达式非常适用于具有。由于反向引用,Perl 5正则表达式的功能更强一些,但一般的经验法则是:

如果您需要匹配方括号(
(…)
[…]
)或其他类似嵌套的HTML标记,那么正则表达式本身是不够的

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

显然,如果你写了一个正则表达式,离开去喝杯咖啡,回来后,不容易理解你刚刚写的东西,那么你应该寻找一种更清晰的方式来表达你正在做的事情。可能已经到了使用正则表达式可以正确且易读地处理的极限

上下文无关 解析器生成器和手工编码的下推/挂起解析器非常适合处理更复杂的输入,您需要处理嵌套,因此可以构建,或者处理或关联

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

CF语法的经验法则是

如果正则表达式不足,但不管之前的声明如何,该语言中的所有单词都具有相同的含义,那么CF可以工作

非上下文无关 如果你的语言中的单词根据上下文而改变意思,那么你需要一个更复杂的解决方案。这些几乎都是手工编码的解决方案

例如,在C中

#ifdef X
  typedef int foo
#endif

foo * bar

如果
foo
是一种类型,则
foo*bar
是名为
bar
foo
指针的声明。否则,它是名为
foo
的变量与名为
bar
的变量的乘积。您应该在需要时使用
何时?我需要一个例子。“我的意思是,你说的有道理,但我需要解释一下你的确切意思。”丹,看看我的答案,了解一个常见的例子。解析CF语言时,通常使用正则表达式将其拆分为标记,然后使用完整的解析器处理该标记流。例如,您可以将
“(a+b)*c”
分解为
[(“,”,“a”,“+”,“,”b“,”,“*”,“c”]
,然后抛出空格并将结果交给解析器处理括号和运算符优先级,以生成类似于
(Times(加上(Var“a”)(Var“b”)(Var“c”)
。有趣的是,您应该提到CSV文件。他们是让我想问这个问题的原因之一。当我说在处理CSV文件时应该使用字符串解析器而不是正则表达式时,我对你的例子的解释正确吗?@Dan,正则表达式可以很好地处理CSV文件——没有任意的深度嵌套,只有两层的深度结构。对于IE样式,您可以使用类似于
/([^\r\n“]|“(?:[^”]|“)*”)/g
的内容查找行,这允许使用双引号对的带引号字符串中的换行符转义双引号。然后,您可以使用类似于
/([^,]|“(?:[^”]|“)*”*/g
的方法在一行中查找字段。然后,您只需要使用/“(?:[^”]|“”)*”/,去掉外部引号,并将所有出现的
替换为
。多年前的问题,但我想指出,CSV通常应该由解析器处理,而不是由正则表达式处理。事实上,csv解析中存在许多意想不到的陷阱和陷阱,您甚至应该使用成熟的库来完成任务,而不是使用自制的解决方案。(除非您在自定义应用程序中控制csv端到端。)@MikeSamuel-“电子邮件地址可能已达到使用正则表达式可以正确且易读地处理的极限。”荒谬。正则表达式确实是一种完全自己的语言,需要很好地理解,但我不这么认为