Erlang手册re模块翻译(一) ——compile函数

一直想写个爬虫,最近在学Erlang就打算用Erlang写,结果Erlang正则表达式不会,网上资料又少,所以就打算把re模块翻译一下。

第一次翻译英文手册,肯定有翻译不对的地方,我尽量先在shell中尝试了在翻译,也会把试过的一些例子放在下面帮助理解。

不对的地方请大家指正,这也仅供一个参考,可以帮助自己以及学习Erlang的朋友理解Erlang的正则表达式。

本文是原创,目前没有在网上找到相关资料。所以如果转载请注明出处。

以下是正文部分:


模块

re

模块摘要

Erlang中类似于perl语言正则表达式的模块

描述

    这个模块包含了正则表达式匹配的字符串和二进制文件的功能。

    正则表达式的语法和语义类似于Perl语言.

    该库的匹配算法目前基于PCRE库,但并没有提供全部PCRE库内容的接口并且该库的一些内容超出了PCRE提供的范围。PCRE库文档中跟当前模块相关的部分包含在这里。

注释

在Erlang语法中,字符串中使用"\"(反斜杠)字符来表示转义字符。如果你需要在文本字符串,或者代码和shell中使用“\”(反斜杠),你需要用额外的一个"\"进行转义,即:用"\\"来表示一个反斜杠。

数据类型

mp() = {re_pattern, term(), term(), term(), term()}

    不透明的数据类型包含一个编译过的正则表达式。mp类型被确定是一个元组,并且其第一个元素为原子‘re_pattern’,用来在条件中匹配。元组中的参数数量或者其他字段的内容可能会在以后的发行版本中改变。

nl_spec() = cr | crlf | lf | anycrlf | any

compile_option() = unicode
                 | anchored
                 | caseless
                 | dollar_endonly
                 | dotall
                 | extended
                 | firstline
                 | multiline
                 | no_auto_capture
                 | dupnames
                 | ungreedy
                 | {newline, 
nl_spec()}
                 | bsr_anycrlf
                 | bsr_unicode
                 | no_start_optimize
                 | ucp
                 | never_utf

导出函数

compile(Regexp) -> {ok, MP} | {error, ErrSpec}

    类型:

    Regexp = iodata()

    MP = mp()

    ErrSpec = 

        {ErrString :: string(), Position :: integer() >= 0}

     该函数相当于调用compile(Regexp, [])。

compile(Regexp, Options) -> {ok, MP} | {error, ErrSpec}

    类型:

    Regexp = iodata() | unicode:charlist()

    Options = [Option]

    Option = compile_option()

    MP = mp()

    ErrSpec = 

        {ErrString :: string(), Position :: integer() >= 0}

    此函数用下面作为参数用在run/2,3函数的内部格式描述的语法来编译一个正则表达式。

    在匹配之前对正则表达式进行预编译对于在程序的生命周期内,一个正则表达式多次使用到的情况很有用。一次编译,多次运行比每次运行前都编译一遍效率要高很多。

    当选择了unicode选项,正则表达式就应该是有效的charlist()类型或者iodata()类型。

    options有以下值:  

  unicode

    正则表达式为Unicode charlist()类型,正则表达式代码被运行在一个有效的Unicode chartlist()程序中。在使用Unicode字符时还需要考虑ucp选项。

  anchored

     正则匹配模式被强制设为"anchored",该模式默认只从待匹配字符串的第一个位置开始匹配。如果从起始位置开始匹配上则返回匹配的起始位置和匹配的字符个数,否则返回原子nomatch。该效果也可以通过适当的修改模式自身来实现。

    eg: 1>{ok,MP}=re:compile("abc",[anchored]). 
            {ok,{re_pattern,0,0,0,<<69,82,67,80,77,0,0,0,16,0,0,0,1,0,0,0,255,255,255,255,255,255,...>>}}
           2> re:run("abcdeabc", MP).
             {match, [{0,3}]} 默认起始位置为0,所以匹配到第一个abc,3代表匹配字符的个数,如果待匹配字符为abcd,匹配成功后这里则为4
           3>re:run("abcdeabc", MP, [{offset, 5}]).
             {match, [5,3]} 这里offset代表从第五个字符开始匹配
           4>re:run("abcdeabc", MP, [{offset, 2}]).
          nomatch  

  caseless

    该模式匹配时会忽略大小写,即大小写字母都匹配。它和Perl正则表达式的i选项一样,而且它可以在模式中用a(?i)选项来设置。此处说的大写字母和小写字母在ISO-8859-1字符集里定义。

  dollar_endonly

    一个$元字符在模式里表示匹配以当前字符串结尾的字符串,并返回由第一个匹配字符的位置以及匹配字符串的长度组成的元组,若匹配失败则返回nomatch。没有这个选项,$符号也会匹配换行符之前的以当前字符串结尾的字符串。该选项如果遇到多行的情况就会被忽略。在Perl正则表达式中没有与之相等价的选项,而且也不能在模式中设置它。

    eg: 1> {ok,MP}=re:compile("abc$",[dollar_endonly]).
               {ok,{re_pattern,0,0,0,<<69,82,67,80,77,0,0,0,32,0,0,0,81,0,0,0,255,255,255,255,255,255,...>>}}
           2> re:run("abcdeabc",MP).
               {match,[{5,3}]}
           3> re:run("abcdeabc",MP,[{capture,all,list},global]).
              {match,[["abc"]]}
           1>re:run("abcdeabc", "abc$").
              {match, [{5,3}]}
           2>re:run("abcdeabc", "abc+$").     注意1,2写法效果都一样
              {match, [{5,3}]}

  dotall

    一个点在模式中表示匹配除换行符之外的任意字符(默认不匹配换行符),该选项让"."在模式中也匹配换行符。该选项相当于Perl正则表达式中的/S选项,并且他可以在模式中用a(?s)选项转变。该选项被设置后,[^a]总是会匹配一个换行符。

    eg:1> {ok,MP}=re:compile(".",[dotall]).
                {ok,{re_pattern,0,0,0,<<69,82,67,80,72,0,0,0,4,0,0,0,1,0,0,0,255,255,255,255,255,255,...>>}}
            2> re:run("abcdeabc", MP, [{capture, all, list}, global]).
               {match,[["a"],["b"],["c"],["d"],["e"],["a"],["b"],["c"]]}
            3> re:run("abcdeabc", MP, [{capture, all, list}]).
               {match,["a"]}
            4> re:run("abcdeabc", MP).
               {match,[{0,1}]}
            5> re:run("abcdeabc", ".").
               {match,[{0,1}]}
            6> re:run("abcdeabc", "[^a]").    [^a]总是会匹配一个换行符
               {match,[{1,1}]}
            7> re:run("\nabcdeabc", "[^a]").
               {match,[{0,1}]}

  extended 

    ​空白字符在模式中将会被忽略,除非是退出或者在一个字符类中。空白字符不包括VT(ASCII 11)字符。此外,处于字符类之外转义#和下一个换行符之间的字符也将被忽略。该选项相当于Perl中的/x选项,它可以通过在模式中设置a(?x)选项来改变。该选项使在复杂的模式中包含注释成为可能。然而请注意,这只能用于数据字符。空白字符可能永远不会出现在模式中的特殊字符序列中,例如序列(?(表示引入一个条件子模式。

  firstline

    ​一个unanchored模式,要求匹配目标字符串之前或者第一个换行符之前的内容,尽管匹配的文本可能会超出换行符的范围。

  multiline

    PCRE默认把主字符串当做只包含单独一行的字符串(即使事实上它包含多行)。行首元字符(^)只匹配字符串的开头,行尾元字符($)只匹配字符串的末尾,或者终止字符串之前(除非dollar_endonly选项被设置)。这和Perl语言中的正则表达式一样。

    当该选项被设置,行首字符和行尾字符构建的表达式会分别匹配行首以后和字符串内部换行符之前的内容。这和Perl中的/m选项相等价,它可以通过在模式中设置a(?m)来更改。如果字符串中没有换行符或者模式中没有^或者$,则该选项无效.(这段不知道该怎么翻译,原文如下)

    原文:When multiline is given, the "start of line" and "end of line" constructs match immediately following or immediately before internal newlines in the subject string, respectively, as well as at the very start and end. This is equivalent to Perl's /m option, and it can be changed within a pattern by a (?m) option setting. If there are no newlines in a subject string, or no occurrences of ^ or $ in a pattern, setting multiline has no effect.

       eg:1> re:run("abcdeabc\nabc", "^a").
                 {match,[{0,1}]}
              2> re:run("abcdeabc\nabc", "^b").
                   nomatch
              3> re:run("abcdeabc\nabc", "$a").
                   nomatch
              4> re:run("abcdeabc\nabc", "$c").
                  nomatch
              5> {ok,MP}=re:compile("^b",[multiline]).
                {ok,{re_pattern,0,0,0,<<69,82,67,80,74,0,0,0,2,0,0,0,65,1,0,0,255,255,255,255,255,255,...>>}}
             6> re:run("abcdeabc\nabc", MP).
                nomatch

  no_auto_capture

    ​禁止使用数字编号来在模式中匹配括号。任何后面没有?的左括号行为就像后面跟着?:一样,但是命名括号仍然可以用于捕获(它们以通常的方式获得数字)。在Perl中没有等价的选项。

  dupnames

    ​用于识别捕获子模式的名字不一定是惟一的。这对于那些已知只有一个子模式的实例能够被匹配的确定类型的模式是很有用的。下面有更多的命名子模式的细节。

  ungreedy

    这句不知道该怎么翻译,原文:This option inverts the "greediness" of the quantifiers so that they are not greedy by default, but become greedy if followed by "?".该选项和Perl语言的正则表达式不兼容。它也可以在模式中通过a(?U)来改变。

    eg:1>{ok,MP}=re:compile("abcd",[ungreedy]).
                 {ok,{re_pattern,0,0,0,<<69,82,67,80,79,0,0,0,0,2,0,0,81,0,0,0,255,255,255,255,255,255,...>>}}
        2> re:run("abcdeabc\nabc", MP, [{capture, all, list}, global]).
            {match,[["abcd"]]}
        3> re:run("abceabc\nabc", MP).
            nomatch
        4> re:run("abceabcd\nabc", MP).
            {match,[{4,4}]}
        1> {ok,MP}=re:compile("abcd?",[ungreedy]).
            {ok,{re_pattern,0,0,0,<<69,82,67,80,79,0,0,0,0,2,0,0,81,0,0,0,255,255,255,255,255,255,...>>}}
    ​  2> re:run("abceabc\nabc", MP, [{capture, all, list}, global]).
    ​    ​{match,[["abc"],["abc"],["abc"]]}
    ​  3> re:run("abceabcd\nabc", MP).    ​问号会少匹配一个字符
    ​    ​{match,[{0,3}]}

  {newline, NLSpec}

    重写目标字符串中默认的换行符(在erlang中为LF(ASCII 10))的定义。

    cr

     换行符由单个字符CR(ASCII 13)表示。

    lf

      换行符有单个字符LF(ASCII 10)(默认选项)表示。

    crlf

     换行符由一个双字符序列CRLF(ASCII 13 ASCII 10)表示。

    anycrlf

     上述三个序列任何一个都应该能被识别。

    any

     上述三个换行符,附加上Unicode字符序列VT(垂直选项卡,U+000B),FF(formfeed,U+000C),NEL(下一行,U+0085),LS(行分割符,U+2028)以及PS(段落分割符,U+2029)。

  bsr_anycrlf

    该选项专门指定\R来只匹配cr,lf或crlf序列,而不是Unicode换行符。

  bsr_unicode

    该选项指定\R来匹配所有的Unicode换行符(默认包含crlf等)。

  no_start_optimize

    该选项禁用可能导致故障的优化,如果”特殊模式启动项目“存在于正则表达式中。一个典型的例子是当用(*COMMIT)ABC来匹配"DEFABC"时,PCRE的启动优化会直接跳过这个指令直接匹配到A,并且永远不会意识到(*COMMIT)指令的存在应该使这个匹配失败。这个选项只和你是否使用"模式启动项目"有关,将会在下面的"PCRE 正则表达式细节"一节中讨论。

  ucp

    指明应该使用Unicode字符属性当解析\B,\b,\D,\d,\S,\s,\Wand,\w时。不设置该选项时,仅仅使用ISO-Latn-1属性。使用Unicode属性会有损性能,但是当以Unicode字符工作时语义正确性远远超过ISO-Latin-1范围。

  never_utf

    指明(*UTF)和/或(*UTF8)”模式启动项目“被禁止。该标志不能和unicode一起使用。它会起作用,如果ISO-Latin-1模式从外部源进行编译。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值