正则表达式是什么\ b相当于并且有没有办法去除它?

时间:2014-04-08 18:58:50

标签: regex perl

我有兴趣更改正则表达式单词边界\b以包含其他字符(例如,.不会计为边界)。我知道它是\w\W字符之间的边界。

  my $_ = ".test";
  if ( /(\btest\b)/ ){
    print;
    print " $1\n";
  }
  if ( /((?:(?<=\W)|^)test(?:(?=\W)|$))/ ){
    print;
    print " $1\n";
  }

这就是我想出来的,我所要做的就是将\W更改为[^\w.],但我仍然想知道Perl如何解释\b一个正则表达式。我试着像这样贬低它:

my $deparser = B::Deparse->new("-sC", "-x10");

print $deparser->coderef2text( sub { 
          my $_ = ".test";
          if ( /(\btest\b)/ ){
            print;
            print " $1\n";
          }
          if ( /((?:(?<=\W)|^)test(?:(?=\W)|$))/ ){
            print;
            print " $1\n";
          }
       });

我希望它能将\b扩展到相当于它的东西。什么是\b相当于?你能以某种方式进一步解析\b或其他表达吗?

2 个答案:

答案 0 :(得分:6)

\b是“一个单词字符”(\w)和“不是单词字符”之间的零宽度边界(这与“非单词字符”{{ 1}})。所以它等同于

\W

Deparsing在这里不起作用,因为正则表达式是直接嵌入到Perl代码中的单独语言。您可以(?<!\w)(?=\w)|(?<=\w)(?!\w) 查看如何编译和匹配正则表达式(有关如何使用此函数的更多信息,请参阅re docs。)

答案 1 :(得分:5)

\b在功能上等同于(?<!\w)(?=\w)|(?<=\w)(?!\w)


Deparse的目标是生成Perl对代码理解的可读表示。例如,f() and g();g() if f();编译相同,因此Deparse将为两者提供更易读的选项g() if f();

$ perl -MO=Deparse -e'f() and g()'
g() if f();
-e syntax OK

如果\b(?<!\w)(?=\w)|(?<=\w)(?!\w)编译为相同的代码,如果Deparse理解编译的正则表达式,它仍然会给你\b。愚蠢不是你想要的。


也许你在考虑简明。它显示了真正执行的内容。请注意以下and

$ perl -MO=Concise,-exec -e'g() if f()'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <0> pushmark s
4  <#> gv[*f] s/EARLYCV
5  <1> entersub[t6] sKS/TARG
6  <|> and(other->7) vK/1
7      <0> pushmark s
8      <#> gv[*g] s/EARLYCV
9      <1> entersub[t3] vKS/TARG
a  <@> leave[1 ref] vKP/REFC
-e syntax OK

但是像Deparse一样,Concise对正则表达式引擎从字符串创建的正则表达式程序一无所知。但是,对于正则表达式模式,有一个等效的简明:use re 'debug';

$ perl -Mre=debug -E'qr/\b/'
Compiling REx "\b"
Final program:
   1: BOUNDU (2)
   2: END (0)
stclass BOUNDU minlen 0
Freeing REx: "\b"

显然,\b是作为自己的操作实现的。为了比较,

$ perl -Mre=debug -E'qr/(?<!\w)(?=\w)|(?<=\w)(?!\w)/'`
Compiling REx "(?<!\w)(?=\w)|(?<=\w)(?!\w)"
Final program:
   1: BRANCH (12)
   2:   UNLESSM[-1] (7)
   4:     POSIXU[\w] (5)
   5:     SUCCEED (0)
   6:   TAIL (7)
   7:   IFMATCH[0] (23)
   9:     POSIXU[\w] (10)
  10:     SUCCEED (0)
  11:   TAIL (23)
  12: BRANCH (FAIL)
  13:   IFMATCH[-1] (18)
  15:     POSIXU[\w] (16)
  16:     SUCCEED (0)
  17:   TAIL (18)
  18:   UNLESSM[0] (23)
  20:     POSIXU[\w] (21)
  21:     SUCCEED (0)
  22:   TAIL (23)
  23: END (0)
minlen 0
Freeing REx: "(?<!\w)(?=\w)|(?<=\w)(?!\w)"