Regex 什么是正则表达式?

Regex 什么是正则表达式?,regex,parsing,Regex,Parsing,我知道这个问题看起来很愚蠢,但事实并非如此。我的意思是它到底是什么。我对解析问题有相当的理解。我知道BNF/EBNF,在我的一门大学课程中,我写过语法来解析简单的上下文无关语言。我以前从未见过正则表达式!关于它,我记得的唯一一件事是上下文无关语法可以做正则表达式所能做的一切 另外,解析字符串对于通常的编码有用吗?举个简单的例子会很有帮助。正则表达式是模式匹配的专用语言。它们在许多文本编辑器和编程语言中用于字符串匹配 你也可以用正则表达式做很多更复杂的事情。有一本关于这个主题的伟大的O'Reill

我知道这个问题看起来很愚蠢,但事实并非如此。我的意思是它到底是什么。我对解析问题有相当的理解。我知道BNF/EBNF,在我的一门大学课程中,我写过语法来解析简单的上下文无关语言。我以前从未见过正则表达式!关于它,我记得的唯一一件事是上下文无关语法可以做正则表达式所能做的一切


另外,解析字符串对于通常的编码有用吗?举个简单的例子会很有帮助。

正则表达式是模式匹配的专用语言。它们在许多文本编辑器和编程语言中用于字符串匹配

你也可以用正则表达式做很多更复杂的事情。有一本关于这个主题的伟大的O'Reilly书,网络上有许多例子

正则表达式不能做的事情是正确的解析,因为正则表达式不足以编码语法。它们专门用于模式匹配,如果您尝试使用它们来解析XML之类的内容,您可能会遇到问题。更具体地说,您不能使用正则表达式解析任意嵌套的递归结构。正则表达式无法很好地解决的一个简单问题示例是一组嵌套的大括号,如C中所示:

int main() {    
    void func() {
    }   
}
您可以让正则表达式在一定程度上解决这个问题,但是随着大括号数量的增加,这个问题的内存需求会任意增加。如果您对更详细的内容感兴趣,请阅读另一个StackOverflow问题,了解为什么这样的构造很难用正则表达式解析:

不同的语言以不同的方式实现正则表达式,但是Perl实现非常流行。与Perl兼容的正则表达式家族称为PCRE,或Perl-CcompatibleRegularExpressions。以下是Perl中一个可以匹配整数的正则表达式示例:

#!/usr/bin/perl

use strict;
use warnings;

match_string( "one-two" );
match_string( "1-2" );

sub match_string {
   my $string = shift;
   if ( $string =~ /(\d+)/ ) {
      print "$string matches!\n";
      print "matched: ", $1, "\n";
   } else {
      print "$string doesn't match!\n";
   }
}  

$ perl test.pl 
one-two doesn't match!
1-2 matches!
matched: 1
在本例中,正则表达式匹配一个或多个数字示例。这是一句话:

   if ( $string =~ /(\d+)/ ) {
阅读这篇文章的方法是:

  • 在条件中,字符串与/之间的正则表达式匹配
  • \d字符转换为数字0-9
  • +表示“一次或多次”
  • parens()表示捕获此匹配,并将其放入一个特殊变量中。因为这是第一场比赛,所以投入1美元
在某些语言(如Perl)中,还可以使用正则表达式进行替换,如下所示:

substitute_string( "one-two" );
substitute_string( "1-2" );

sub substitute_string {
   my $string = shift;
   print "before: ",  $string, "\n";
   $string =~ s/1/one/g;
   $string =~ s/2/two/g;
   print "after: ",  $string, "\n";
}

$ perl test.pl 
before: one-two
after: one-two
before: 1-2
after: one-two

希望这足以让你开始

其他人已经讨论了正则表达式是什么,它可以用于什么,所以我不会重复以前的答案。但是,如果您对学习正则表达式语法(即如何构造正则表达式)感兴趣,请访问regular-expression.info;它可能是互联网上最深入的正则表达式语法资源。

正则表达式最早出现在数学和自动机理论中。正则表达式只是定义一个表达式的东西。不必过多地探讨“常规”的含义,可以这样看待一种语言:

  • 语言是由字符串组成的。例如,英语是一种语言,它是由字符串组成的
  • 这些字符串是由符号组成的,称为字母表。所以字符串只是字母表中符号的串联
  • 因此,您可以有一个字符串(记住,它只是符号的串联),它不是给定语言的一部分。也可能是语言

    假设你有一个由两个符号组成的字母表:“0”和“1”。假设你想用字母表中的符号创造一种语言。您可以创建以下规则:“为了使字符串使用我的语言,其中必须只有0和1。”

    因此,这些字符串使用您的语言:

    • 0
    • 一,
    • 01
    • 11001101
    • …等等
    这些不是您的语言:

    • 二,
    • 桃子
    • 00101105
    这是一种非常简单的语言。这样如何:“在我的语言中,每个字符串[类似于英语中的有效“单词”)必须是0,然后可以后跟任意数量的0或1”

    这些语言是:

    • 011111
    • 0000000
    • 010101011001
    这些不是:

    • 一,
    • 一万
    • 1010
    • 200万
    我们没有使用单词来定义语言——这些语言可能会变得非常复杂(“1后面跟2 0,然后是1和0的任意组合,最后是1”),而是提出了一种称为“正则表达式”的语法来定义语言

    第一种语言应该是:

    (0|1)*

    (0或1,无限重复)

    下一个:
    0(0|1)*

    (0,后跟任意数量的0和1)

    现在让我们考虑一下编程。当你创建一个正则表达式时,你说的是“看看这个文本。返回给我匹配这个模式的字符串。”这实际上是说“我已经定义了一种语言。返回给我这个文档中所有使用我的语言的字符串。”

    所以,当你创建一个“正则表达式”时,你实际上是在定义一种正则语言,这是一个数学概念。(实际上,类似perl的正则表达式定义了“非规则”语言,但这是另一个问题。)

    通过学习regex的语法,您可以了解如何创建语言的细节,以便以后可以查看给定字符串是否“在”该语言中。因此,人们通常说正则表达式用于模式匹配——这基本上就是当您查看模式并查看它是否“匹配”您的语言规则时所做的

    (这很长。它回答了你的问题吗?

    好的解释