12

好吧,我几乎不了解 RegEx 基础知识,但为什么他们不能将其设计为使用关键字(如 SQL)而不是一些神秘的通配符和符号?

由于 RegEx 在运行时被解释/解析,是为了性能吗?(未编译)

或者也许是为了写作速度?考虑到当您学习一些“简单”的字符组合时,键入 1 个字符而不是关键字会变得更容易?

4

14 回答 14

35

你真的想要这个

Pattern findGamesPattern = Pattern.With.Literal(@"<div")
    .WhiteSpace.Repeat.ZeroOrMore
    .Literal(@"class=""game""").WhiteSpace.Repeat.ZeroOrMore.Literal(@"id=""")
    .NamedGroup("gameId", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal(@"-game""")
    .NamedGroup("content", Pattern.With.Anything.Repeat.Lazy.ZeroOrMore)
    .Literal(@"<!--gameStatus")
    .WhiteSpace.Repeat.ZeroOrMore.Literal("=").WhiteSpace.Repeat.ZeroOrMore
    .NamedGroup("gameState", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal("-->");

好的,但这是你的葬礼,伙计。

在此处下载执行此操作的库:http:
//flimflan.com/blog/ReadableRegularExpressions.aspx

于 2009-03-10T10:32:26.640 回答
10

正则表达式具有数学(实际上是语言理论)背景,其编码方式有点像数学公式。您可以通过一组规则来定义它们,例如

  • 每个字符都是一个正则表达式,代表它自己
  • if aandb是正则表达式,thena?a|bandab也是正则表达式
  • ...

使用基于关键字的语言对于简单的正则表达式来说是一个很大的负担。大多数时候,您只会使用简单的文本字符串作为搜索模式:

grep -R 'main' *.c

或者可能是非常简单的模式:

grep -c ':-[)(]' seidl.txt

一旦你习惯了正则表达式,这种语法就会非常清晰和精确。在更复杂的情况下,您可能会使用其他东西,因为大型正则表达式显然难以阅读。

于 2009-03-10T10:30:05.103 回答
8

Perl 6 在正则表达式的可读性方面迈出了革命性的一步。考虑以下形式的地址:100 E Main St Springfield MA 01234

这是一个可读性适中的 Perl 5 兼容正则表达式来解析它(许多极端情况未处理):

 m/
     ([1-9]\d*)\s+
     ((?:N|S|E|W)\s+)?
     (\w+(?:\s+\w+)*)\s+
     (ave|ln|st|rd)\s+
     ([:alpha:]+(?:\s+[:alpha:]+)*)\s+
     ([A-Z]{2})\s+
     (\d{5}(?:-\d{4})?)
  /ix;

这个 Perl 6 正则表达式具有相同的行为:

grammar USMailAddress {
     rule  TOP { <addr> <city> <state> <zip> }

     rule  addr { <[1..9]>\d* <direction>?
                  <streetname> <streettype> }
     token direction { N | S | E | W }
     token streetname { \w+ [ \s+ \w+ ]* }
     token streettype {:i ave | ln | rd | st }
     token city { <alpha> [ \s+ <alpha> ]* }
     token state { <[A..Z]>**{2} }
     token zip { \d**{5} [ - \d**{4} ]? }
  }

Perl 6 语法是一个类,标记都是可调用的方法。像这样使用它:

if $addr ~~ m/^<USMailAddress::TOP>$/ {
     say "$<city>, $<state>";
}

这个例子来自Frozen Perl 2009研讨会上的一次演讲。Perl 6 的 Rakudo 实现已经足够完整,以至于这个例子在今天仍然有效。

于 2009-03-15T17:52:57.070 回答
7

好吧,如果您有关键字,您如何轻松地将它们与实际匹配的文本区分开来?你将如何处理空格?

原文公司:A 部门:B

标准正则表达式:

Company:\s+(.+)\s+Dept.:\s+(.+)

甚至:

Company: (.+) Dept. (.+)

关键字正则表达式(真的很努力没有得到一个稻草人......)

"Company:" whitespace.oneplus group(any.oneplus) whitespace.oneplus "Dept.:" whitespace.oneplus group(any.oneplus)

或简化:

"Company:" space group(any.oneplus) space "Dept.:" space group(any.oneplus)

不,这可能不会更好。

于 2009-03-10T10:34:54.640 回答
5

因为它对应于形式语言理论并且是数学符号。

于 2009-03-10T10:27:46.997 回答
4

这是 Perl 的错……!

实际上,更具体地说,正则表达式来自早期的 Unix 开发,当时更加重视简洁的语法。存储、处理时间、物理终端等都非常有限,与今天不同。

维基百科上正则表达式的历史解释了更多。

Regex 有替代品,但我不确定是否真的流行起来。

编辑:由 John Saunders 更正:正则表达式由 Unix普及,但首先由QED编辑器实现。同样的设计约束也适用于早期的系统。

于 2009-03-10T10:20:15.547 回答
3

实际上,不,世界并不是从 Unix 开始的。如果您阅读 Wikipedia 文章,您会看到

在 1950 年代,数学家 Stephen Cole Kleene 使用称为正则集的数学符号描述了这些模型。SNOBOL 语言是模式匹配的早期实现,但与正则表达式不同。Ken Thompson 将 Kleene 的符号构建到编辑器 QED 中,作为匹配文本文件中模式的一种手段。他后来将此功能添加到 Unix 编辑器中,最终导致流行的搜索工具 grep 使用正则表达式

于 2009-03-10T10:27:57.917 回答
2

这比 PERL 早得多。Wikipedia 关于正则表达式的条目将正则表达式的第一个实现归功于 UNIX 名人的 Ken Thompson,他在 QED 和ed编辑器中实现了它们。我猜这些命令出于性能原因有短名称,但在客户端之前。Mastering Regular Expressions是一本关于正则表达式的好书,它提供了注释正则表达式(使用 /x 标志)的选项,使其更易于阅读和理解。

于 2009-03-10T10:29:22.983 回答
1

因为正则表达式的想法——就像许多源自 UNIX 的东西一样——是它们很简洁,有利于简洁而不是可读性。这实际上是一件好事。我最终编写了 15 行长的正则表达式(根据我更好的判断)。如果它有一个冗长的语法,它就不是一个正则表达式,它是一个程序。

于 2009-03-10T10:25:33.943 回答
1

实现正则表达式的“冗长”形式实际上非常容易——请在此处查看我的答案。简而言之:编写一些返回正则表达式字符串的函数(并在必要时获取参数)。

于 2009-03-10T10:26:59.040 回答
1

我认为关键字不会带来任何好处。正则表达式本身很复杂,但也非常强大。

我认为更令人困惑的是,每个支持库都发明了自己的语法,而不是使用(或扩展)经典的 Perl 正则表达式(例如 \1、$1、{1}、... 用于替换和更多示例)。

于 2009-03-10T11:16:11.967 回答
1

我知道它以错误的方式回答你的问题,但RegExBuddy有一个功能可以用简单的英语解释你的正则表达式。这可能会使它更容易学习。

于 2009-03-10T11:51:43.987 回答
1

如果您使用的语言支持Posix 正则表达式,您可以使用它们。

一个例子:

\d

将与

[:digit:]

括号符号在匹配的内容上更加清晰。我仍然会学习“神秘的通配符和符号,因为您仍然会在其他人的代码中看到它们并且需要理解它们。

在 regular-expressions.info's page 的表格中有更多示例。

于 2009-03-15T18:20:11.683 回答
1

由于某种原因,我之前的答案被删除了。无论如何,我认为 ruby​​ 正则表达式机器符合要求,在http://www.rubyregexp.sf.net。这是我自己的项目,但我认为它应该可以工作。

于 2011-07-01T15:43:36.297 回答