Skip to content

Latest commit

 

History

History
199 lines (148 loc) · 4.78 KB

10.3.正则表达式.md

File metadata and controls

199 lines (148 loc) · 4.78 KB

10.3.正则表达式

Haxe 内置支持 正则表达式。它们可以用来验证字符串格式,转换一个字符串,或者从给定文本中提取一些规则数据。

Haxe创建正则表达式有特定的语法。我们可以创建一个正则表达式对象通过输入其到 ~/ 组合和一个单独的 / 符号中:

var r = ˜/haxe/i; 

或者,我们可以使用正则语法创建正则表达式:

var r = new EReg("haxe", "i");

第一个参数是正则表达式模式字符串,第二个是标记字符串(后面查看)。

我们可以使用标准的正则表达式模式,如:

  • . 任何字符
  • * 重复0或者多次
  • + 重复1或者多次
  • ? 可选的0或者1次
  • [A-Z0-9] 字符范围
  • [ˆ\r\n\t] 不在范围内的字符
  • (...) 括号匹配字符的分组
  • ˆ 字符串起始字符(在多行匹配模式中一行的起始字符)
  • $ 字符串的尾字符(多行匹配模式下一行的尾字符)
  • | "OR"语句

例如,下面的增则表达式匹配有效的 email 地址:

~/[A-Z0-9._\%-]+@[A-Z0-9.-]+\.[A-Z][A-Z][A-Z]?/i; 

注意 正则表达式结尾的 i 是一个标记,作用是启用不区分大小写的匹配。

可能的标记如下:

  • i 不区分大小写匹配
  • g 全局替换或者分割,查看后面
  • m 多行匹配, ˆ 和 $ 表示一行的开头和结尾
  • s 点号 . 将也匹配新行(Neko,C++,PHP,Flash 和Java 目标)
  • u 使用UTF-8匹配(Neko 和 C++目标)

查看EReg API 详细了解它的方法。

10.3.1.匹配

可能正则表达式最常用的一个地方就是检查一个字符串是否匹配特定模式。正则表达式对象的 match 方法可以用来做这些:

class Main {
  static function main() {
    var r = ~/world/;
    var str = "hello world";
    // true : 'world' was found in the string
    trace(r.match(str));
    trace(r.match("hello !")); // false
  }
}

10.3.2.分组

通过使用分组,特定信息可以被从一个匹配的字符串中提取。如果 match() 返回 true,我们可以使用 matched(X) 方法过的分组,X是正则表达似乎模式定义的分组的号码:

class Main {
  static function main() {
    var str = "Nicolas is 26 years old";
    var r =
      ~/([A-Za-z]+) is ([0-9]+) years old/;
    r.match(str);
    trace(r.matched(1)); // "Nicolas"
    trace(r.matched(2)); // "26"
  }
}

注意,分组号从1开始,r.matched(0) 总是返回整个匹配的子串。

r.matchedPos() 返回这个子串在原字符串中的位置:

class Main {
  static function main() {
    var str = "abcdeeeeefghi";
    var r = ~/e+/;
    r.match(str);
    trace(r.matched(0)); // "eeeee"
    // { pos : 4, len : 5 }
    trace(r.matchedPos());
  }
}

另外,r.matchedLeft() 和 r.matchedRight() 可以用来获得匹配的子串左侧或者右侧的子串:

class Main {
  static function main() {
    var r = ~/b/;
    r.match("abc");
    trace(r.matchedLeft()); // a
    trace(r.matched(0)); // b
    trace(r.matchedRight()); // c
  }
}

10.3.3.替换

一个正则表达式也可以被用于替换字符串的一部分:

class Main {
  static function main() {
    var str = "aaabcbcbcbz";
    // g : replace all instances
    var r = ~/b[^c]/g;
    // "aaabcbcbcxx"
    trace(r.replace(str,"xx"));
  }
}

在替换中,我们可以使用 $X 来重用一个匹配的组:

class Main {
  static function main() {
    var str = "{hello} {0} {again}";
    var r = ~/{([a-z]+)}/g;
    // "*hello* {0} *again*"
    trace(r.replace(str,"*$1*"));
  }
}

10.3.4.分割

一个正则表达式也可以用来分割一个字符串到几个子串:

class Main {
  static function main() {
    var str = "XaaaYababZbbbW";
    var r = ~/[ab]+/g;
    // ["X","Y","Z","W"]
    trace(r.split(str));
  }
}

10.3.5.Map

正则表达式对象的 map 方法可以用于使用一个自定义函数替换匹配的子串。这个函数把一个正则表达式对象作为第一个参数,所以我们可以使用它得到进行匹配的更多信息,并进行条件替换。例如:

class Main {
  static function main() {
    var r = ~/(dog|fox)/g;
    var s = "The quick brown fox jumped over the lazy dog.";
    var s2 = r.map(s, function(r) {
        var match = r.matched(0);
        switch (match) {
            case 'dog': return 'fox';
            case 'fox': return 'dog';
            default: throw 'Unknown animal: $match';
        };
    });
    trace(s2); // The quick brown dog jumped over the lazy fox.
  }
}

10.3.6.实现细节

正则表达式的实现:

  • 在JavaScript中,运行时使用对象 RegExp 提供实现。
  • 在Neko 和C++中,使用 PCRE 库。
  • 在Flash、PHP、C#和Java中,使用原生的实现。
  • 在Flash 6 /8 中,实现不可用。