【问题标题】:Regex using Vala and GLib使用 Vala 和 GLib 的正则表达式
【发布时间】:2014-12-30 15:49:23
【问题描述】:

有没有类似http://php.net/manual/en/function.preg-match-all.php的函数?

使用 GLib http://references.valadoc.org/#!api=glib-2.0/GLib.MatchInfo,我发现的只是:

public bool match_all_full (string str, ssize_t string_len = -1, int start_position = 0,  RegexMatchFlags match_options = 0, out MatchInfo match_info = null) throws RegexError
Using the standard algorithm for regular expression matching only the longest match in the string is retrieved, it is not possible to obtain all the available matches. 

它说不可能获得所有可用的匹配项。

我找不到任何有效的代码示例。感谢您的帮助。

注意:

目标是解析一个 plist 文件(我只需要 CFBundleIdentifier 和 CFBundleName 值)

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>CFBundleIdentifier</key>
    <string>nodejs</string>
    <key>CFBundleName</key>
    <string>Node.js</string>
    <key>DocSetPlatformFamily</key>
    <string>nodejs</string>
    <key>isDashDocset</key><true/><key>dashIndexFilePath</key><string>nodejs    /api/documentation.html</string></dict>
</plist>

我有这些依赖项(ubuntu synapse 包):

Build-Depends: debhelper (>= 9),
dh-autoreconf,
gnome-common,
valac (>= 0.16.0),
libzeitgeist-2.0-dev (>= 0.9.14),
libdbus-glib-1-dev,
libgtk-3-dev (>= 3.0.0),
libglib2.0-dev (>= 2.28.0),
libgee-0.8-dev (>= 0.5.2),
libjson-glib-dev (>= 0.10.0),
libkeybinder-3.0-dev,
libnotify-dev,
librest-dev,
libappindicator3-dev (>= 0.0.7)

结果它给了我

** Message: main.vala:28: CFBundleIdentifier: cakephp
** Message: main.vala:28: CFBundleName: CakePHP
** Message: main.vala:28: DocSetPlatformFamily: cakephp

关于为什么不使用 xmllib 的问题? 该项目几乎没有依赖项,在 GNU 系统中(尽管我是新手),程序被打包假设只有某些依赖项,如果我不想使用我的插件,我想我必须只使用可用的依赖项或者我可能会破坏某些东西并阻止endsudoer的更新。

【问题讨论】:

标签: regex linux glib vala


【解决方案1】:

首先,让我们看一下您引用的引用的一些上下文,并强调:

使用标准算法进行正则表达式匹配,只检索字符串中最长的匹配项,不可能获得所有可用的匹配项。例如,将“&lt;a&gt; &lt;b&gt; &lt;c&gt;”与模式“&lt;.*&gt;”匹配会得到“&lt;a&gt; &lt;b&gt; &lt;c&gt;”。

此函数使用不同的算法(称为 DFA,即确定性有限自动机),因此它可以检索所有可能的匹配项,所有匹配项都从字符串中的同一点开始。例如,将“&lt;a&gt; &lt;b&gt; &lt;c&gt;”与“&lt;.*&gt;;”模式匹配,您将获得三个匹配项:“&lt;a&gt; &lt;b&gt; &lt;c&gt;”、“&lt;a&gt; &lt;b&gt;”和“&lt;a&gt;”。

也就是说,这并不是您要寻找的“全部”——您的情况要简单得多。您需要做的就是遍历标准算法中的匹配项:

private static int main (string[] args) {
    string contents;
    GLib.Regex exp = /\<key\>([a-zA-Z0-9]+)\<\/key\>[\n\t ]*\<string\>([a-zA-Z0-9\.]+)\<\/string\>/;

    assert (args.length > 1);
    try {
        GLib.FileUtils.get_contents (args[1], out contents, null);
    } catch (GLib.Error e) {
        GLib.error ("Unable to read file: %s", e.message);
    }

    try {
        GLib.MatchInfo mi;
        for (exp.match (contents, 0, out mi) ; mi.matches () ; mi.next ()) {
            GLib.message ("%s: %s", mi.fetch (1), mi.fetch (2));
        }
    } catch (GLib.Error e) {
        GLib.error ("Regex failed: %s", e.message);
    }

    return 0;
}

【讨论】:

  • 你的答案会很好,但这可能根本不起作用,因为不能保证 节点在同一行。
  • 谢谢各位,数据源是自动下载的zeal文档,可能是有点靠谱的数据源。我认为它也可以作为一个 plist 来验证它的 DTD。我会尝试上面的正则表达式解决方案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 2014-03-29
相关资源
最近更新 更多