首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SMLNJ中使用regex

如何在SMLNJ中使用regex
EN

Stack Overflow用户
提问于 2016-02-17 16:55:04
回答 1查看 1K关注 0票数 2

我想输入一个字符串,然后查看它是否与某个正则表达式匹配;如果不是,我想继续使用另一个正则表达式,直到我的所有正则表达式都用完为止。例如,假设我有以下三个正则表达式

  • regex_1 =a*
  • regex_2 = 0-9*
  • regex_3 =(1 1tom\2 2jerry)

现在假设所需的字符串是:

代码语言:javascript
复制
- val str_input="7569"

我想先检查str_input与regex_1;if不匹配,然后尝试与regex_2;if不匹配,最后尝试与regex_3匹配,问题是如何使用SMLNJ实现这个目的。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-17 19:16:08

您可以使用SML/NJ提供的正则表达式库实现您想要的结果。它的文档可以在这里找到:http://www.smlnj.org/doc/smlnj-lib/Manual/regexp-lib-part.html

作为一个小的入门例子,下面是您需要做的事情。首先,您需要告诉SML/NJ您想要使用regexp库。您可以使用一个.cm文件(cm来自编译管理器,它类似于SML/NJ的Makefile )来完成这一任务:

sources.cm

代码语言:javascript
复制
group is
  $/basis.cm      (* Load standard functions and modules. *)
  $/regexp-lib.cm (* Load the regexp library.             *)
  main.sml        (* Load our own source file.            *)

现在我们可以使用regexp库了。不幸的是,这并不是很简单,因为它使用了函子和读取器,但基本上,您需要的是RE.match函数,它接受一组对,其中第一个元素是正则表达式,第二个是匹配regexp时调用的函数。使用此对列表,RE.match函数将遍历输入字符串,直到找到匹配的字符串,这时它将调用与该匹配点匹配的regexp关联的函数。该函数的结果是整个RE.match调用的结果。

main.sml

代码语言:javascript
复制
structure Main =
  struct
    (**
     * RE is a module created by calling the module-level function (functor)
     * RegExpFn (Fn comes from functor), with two module arguments.
     *
     * The first argument, called P, is the syntax used to write regular
     * expressions in. In this particular case, it's the Awk syntax, which
     * is the only syntax provided by SML/NJ right now.
     *
     * The second argument, called E, is the RegExp engine used behind the
     * scenes to compile and execute the syntax. In this particular case
     * I've opted for ThompsonEngine, which implements Ken Thompson's
     * matching algorithm. Other options are BackTrackEngine and DfaEngine.
     *)
    structure RE = RegExpFn(
      structure P = AwkSyntax
      structure E = ThompsonEngine
      (* structure E = BackTrackEngine *)
      (* structure E = DfaEngine *)
    )

    fun main () =
      let
        (**
         * A list of (regexp, match function) pairs. The function called by
         * RE.match is the one associated with the regexp that matched.
         *
         * The match parameter is described here:
         *   http://www.smlnj.org/doc/smlnj-lib/Manual/match-tree.html
         *)
        val regexes = [
          ("[a-zA-Z]*",   fn match => ("1st", match)),
          ("[0-9]*",      fn match => ("2nd", match)),
          ("1tom|2jerry", fn match => ("3rd", match))
        ]
        val input = "7569"
      in
        (**
         * StringCvt.scanString will traverse the `input` string and apply
         * the result of `RE.match regexes` to each character in the string.
         *
         * It's sort of a streaming matching process. The end result, however,
         * depends on your implementation above, in the match functions.
         *)
        StringCvt.scanString (RE.match regexes) input
      end
  end

您现在可以在命令行中这样使用它:

代码语言:javascript
复制
$ sml sources.cm
Standard ML of New Jersey v110.79 [built: Sun Jan  3 23:12:46 2016]
[scanning sources.cm]
[library $/regexp-lib.cm is stable]
[parsing (sources.cm):main.sml]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-BASIS/(basis.cm):basis-common.cm is stable]
- Main.main ();
[autoloading]
[autoloading done]
val it = SOME ("2nd",Match ({len=4,pos=0},[]))
  : (string * StringCvt.cs Main.RE.match) option

文档

  • REGEXP.match
  • MatchTree
  • StringCvt
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35462919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档