为什么正则表达式不能使用关键字而不是字符?

Rob*_*cks 11 regex language-design

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

它是否因为在运行时解释/解析RegEx而具有性能?(未编译)

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

Jef*_*ood 34

你真的想要这个吗?

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("-->");
Run Code Online (Sandbox Code Playgroud)

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

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

  • 呸! 无耻的博客营销......羞耻!:-) (6认同)
  • 这实际上离我的Python模块不远,pyparsing,我认为这个的pyparsing版本会是这样的:`findGamesPattern =("<div"+ ZeroOrMore('class ="game"')+ ZeroOrMore('id = ')+ Word(nums)("gameId")+"-game"+ SkipTo("</ div>")("content")+"</ div>"+"<! - gameStatus"+ Word( "=")+ Word(nums)("gameState")+" - >")` (2认同)

Fer*_*yer 10

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

  • 每个字符都是一个正则表达式,代表自己
  • 如果ab是正则表达式,然后a?,a|b并且ab是正则表达式,也
  • ...

对于简单的正则表达式,使用基于关键字的语言将是一个很大的负担.大多数情况下,您只需使用简单的文本字符串作为搜索模式:

grep -R 'main' *.c
Run Code Online (Sandbox Code Playgroud)

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

grep -c ':-[)(]' seidl.txt
Run Code Online (Sandbox Code Playgroud)

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

  • 当正则表达式看起来像表情时,我喜欢: - [) (3认同)

Chr*_*lan 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;
Run Code Online (Sandbox Code Playgroud)

这个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} ]? }
  }
Run Code Online (Sandbox Code Playgroud)

Perl 6语法是一个类,令牌都是可调用的方法.像这样使用它:

if $addr ~~ m/^<USMailAddress::TOP>$/ {
     say "$<city>, $<state>";
}
Run Code Online (Sandbox Code Playgroud)

这个例子来自Frozen Perl 2009研讨会上发表的演讲.Perl 6的Rakudo实现足够完整,这个例子今天起作用了.


use*_*035 7

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

来源文本公司:A部门:B

标准正则表达式:

Company:\s+(.+)\s+Dept.:\s+(.+)
Run Code Online (Sandbox Code Playgroud)

甚至:

Company: (.+) Dept. (.+)
Run Code Online (Sandbox Code Playgroud)

关键字正则表达式(尝试真的很难得到一个稻草人...)

"Company:" whitespace.oneplus group(any.oneplus) whitespace.oneplus "Dept.:" whitespace.oneplus group(any.oneplus)
Run Code Online (Sandbox Code Playgroud)

或简化:

"Company:" space group(any.oneplus) space "Dept.:" space group(any.oneplus)
Run Code Online (Sandbox Code Playgroud)

不,这可能不会更好.


not*_*row 5

因为它对应于形式语言理论,它是数学符号.