Существует ряд вещей, которые можно сделать, чтобы улучшить код Vala:
- Привязка GLib
Regex
к PCRE вернет сообщение об ошибке, содержащее некоторые сведения о недопустимом регулярном выражении.В Vala это сообщение можно прочитать, поместив new Regex ()
в блок try...catch
. regex.match()
возвращает true
, когда совпадение найдено, поэтому перенос regex.match()
в оператор if
делаетболее надежная программа - В Vala есть оператор объединения нулей
??
, который является удобным способом предоставления альтернативного значения при наличии нулевого значения MatchInfo
имеет next()
метод и в сочетании с циклом 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
является нулевым для второго матча, мне неясно.Это требует дополнительного изучения того, что происходит в движке регулярных выражений, но, надеюсь, этого достаточно, чтобы продолжить.