Vala正则表达式将组与子组结合使用,始终以segmentationfault结尾

时间:2018-11-23 22:39:34

标签: regex vala

这真的很简单。我正在尝试使用正则表达式来识别vcard字符串行中的某些属性值。

所以,这是代码:

int main(string[] args){

string input = "TEL;VALUE=uri;PREF=1;TYPE=\"voice,home\":tel:+1-555-555-5555;ext=5555";



string regString = "(tel:(?<phnum>.*);)*(?<pref>PREF=1;)*";

Regex regex = new Regex(regString);
MatchInfo match;

regex.match(input_end, 0, out match);

stdout.printf(match.fetch_named("phnum"));

stdout.printf(match.fetch_named(pref));

return 0;

}

实际上,我要说的是,标记phnum在输入中出现时才应用于字符的子组(因此,在该组的外部为*)。因此,当我执行match.fetch_named("phnum")时,返回值将是:“ + 1-555-555-5555”。

即使正则表达式测试器应用似乎似乎已经很好地接受了模式,我还是遇到了细分错误。

4 个答案:

答案 0 :(得分:1)

printf首先采用格式字符串。您需要将其更改为:

stdout.printf("%s\n", match.fetch_named("phnum"));

stdout.printf("%s\n", match.fetch_named("pref"));

如果格式字符串为null,则printf将发生段错误。

如果您不想打扰格式字符串,可以使用FileStream.puts,但仍然需要进行空检查:

if (match.fetch_named("phnum")!=null)
  stdout.puts(match.fetch_named("phnum"));

答案 1 :(得分:1)

考虑到regex.match(input_end也应该是regex.match(input

不考虑电话号码的确切格式,一种可能的解决方案是匹配character class中允许的字符并从名为phnum的组中获取值

tel:(?<phnum>[0-9+-]+)

Regex demo | Test it online

或更广泛的匹配可能是使用否定的字符类[^来匹配您不需要的字符类并从名为phnum的组中获取值

tel:(?<phnum>[^\r\n;]+)

Regex demo

答案 2 :(得分:1)

可以做很多事情来改进Vala代码:

  • GLib与PCRE的Regex绑定将返回一条错误消息,其中提供有关无效正则表达式的一些详细信息。在Vala中,可以通过将new Regex ()放在try...catch块中来读取此消息。
  • regex.match()在找到匹配项时返回true,因此将regex.match()包裹在if语句中使程序更加健壮
  • Vala具有空合并运算符??,这是在存在空值时提供替代值的便捷方法
  • MatchInfo具有next()方法,当与Vala的do {} when ()循环结合使用时,可以很好地安全地检索多个匹配项

您使用的正则表达式需要排除终止字符;。因此,tel:(?<phnum>[^;|.]*);将匹配;之后的除tel:以外的所有字符,直到达到;

这是一个将所有内容整合在一起的工作示例:

int main () {

  string input = "TEL;VALUE=uri;PREF=1;TYPE=\"voice,home\":tel:+1-555-555-5555;ext=5555";

  string regString = "tel:(?<phnum>[^;|.]*);|PREF=(?<pref>[0-9]*);";
  Regex regex;
  MatchInfo match;
  try {
    regex = new Regex(regString);
    if (regex.match(input, 0, out match)) {
      do {
        stdout.printf("Phone number: %s\n", match.fetch_named("phnum") ?? "None");
        stdout.printf("Preference: %s\n", match.fetch_named("pref") ?? "None");
      }
      while (match.next());
    }
  }
  catch (Error error) {
    print (@"$(error.message)\n");
    return 1;
  }

  return 0;
}

这将输出:

Phone number: 
Preference: 1
Phone number: +1-555-555-5555
Preference: None

有两场比赛。有趣的是,第一个匹配返回空字符串作为电话号码。这是因为它是有效的子模式,但没有任何匹配项。我不清楚为什么第二场比赛的pref为空。关于正则表达式引擎中发生的事情,还需要进行更多的调查,但这希望可以为您提供足够的继续学习的机会。

答案 3 :(得分:0)

您的正则表达式应缩短为:

tel:(?<phnum>.*);$

现在'phnum'组将包含电话号码。