正则表达式需要在某个表达式之上和之下获得几行(在MATLAB中)

时间:2015-11-05 19:14:27

标签: regex xml string matlab xml-parsing

我希望这里的专家能够帮助我使用正则表达式,我可以在MATLAB中使用它来获取非常大的数据文件的某些部分(262 MB,4588786行和252498496个字符没有空白! )。

我有以下文字作为输入。

text = ['<node id="1672189900" lat="48.2212788" lon="11.4783959" version="6" timestamp="2015-05-03T23:00:27Z" changeset="30762503" uid="145231" user="woodpeck_repair">'...
             '<tag k="ref" v="14839"/>'...
             '<tag k="power" v="sub_station"/>'...
             '<tag k="operator" v="Isar-Amperwerke"/>'...
        '</node>'...
        '<node id="298991549" lat="52.651949" lon="10.267974" version="9" timestamp="2009-03-26T12:53:35Z" changeset="860721" uid="13203" user="bahnpirat">'...
             '<tag k="ref" v="105"/>'...
             '<tag k="power" v="tower"/>'...
        '</node>'...
        '<node id="309209822" lat="47.9339823" lon="11.1047609" version="1" timestamp="2008-11-01T19:21:22Z" changeset="651519" uid="39150" user="account_deleted_1011"/>'...
        '<node id="309209824" lat="47.9342688" lon="11.1048045" version="1" timestamp="2008-11-01T19:21:22Z" changeset="651519" uid="39150" user="account_deleted_1011"/>'...
        '<node id="309245115" lat="48.074924" lon="11.6531406" version="6" timestamp="2014-02-03T21:13:35Z" changeset="20361115" uid="8748" user="ToniE">'...
             '<tag k="power" v="substation"/>'...
             '<tag k="source" v="survey"/>'...
             '<tag k="operator" v="Energieversorgung Ottobunn"/>'...
        '</node>'...
        '<node id="309424891" lat="52.5676698" lon="13.0440382" version="4" timestamp="2015-03-08T19:18:44Z" changeset="29337113" uid="2149159" user="bergaufsee">'...
             '<tag k="power" v="substation"/>'...
        '</node>'];

我需要过滤掉其中包含标记<tag k="power" v="sub(_)?station"/>的三个节点。即我需要在这个标签的上方和下方留几行,这些应该是我的三个匹配。

匹配1:

'<node id="1672189900" lat="48.2212788" lon="11.4783959" version="6" timestamp="2015-05-03T23:00:27Z" changeset="30762503" uid="145231" user="woodpeck_repair">'...
             '<tag k="ref" v="14839"/>'...
             '<tag k="power" v="sub_station"/>'...
             '<tag k="operator" v="Isar-Amperwerke"/>'

比赛2:

<node id="309245115" lat="48.074924" lon="11.6531406" version="6" timestamp="2014-02-03T21:13:35Z" changeset="20361115" uid="8748" user="ToniE">'...
             '<tag k="power" v="substation"/>'...
             '<tag k="source" v="survey"/>'...
             '<tag k="operator" v="Energieversorgung Ottobunn"/>'

比赛3:

<node id="309424891" lat="52.5676698" lon="13.0440382" version="4" timestamp="2015-03-08T19:18:44Z" changeset="29337113" uid="2149159" user="bergaufsee">'...
             '<tag k="power" v="substation"/>'

凭借我有限的知识和一些帮助,我有了这个表达

substation_nodes = regexp(text, '(<node.*?\">(.|\n)*?)(?=<\/node>)','match');

实现此结果但不包含仅包含所需标记的节点。它为我提供了带标签的所有节点。

我尝试过多次修改上面的表达但无济于事。如果有人能帮我找到所需的正则表达式,我将非常感激。

提前致谢!

1 个答案:

答案 0 :(得分:0)

  1. 我的第一个建议是学会使用MATLAB的内置xmlread()函数。

  2. 如果您真的想用代码执行此操作,我会将其解析为文本文件:

    function [context] = getTagWithContext(filename, tagstr)
    fid = open(filename)
    context1 = fgetl(fid);
    context2 = fgetl(fid);
    while true
        line = fgetl(fid);
        if ~ischar(line), break; end; % break out of loop at end of file
    
        if ~isempty(strfind(line, tagstr))
             context = [context1 context2 line];
             return;
        else
             context1 = context2;
             context2 = line;
        end
    end
    
  3. 您可以以显而易见的方式添加上下文行,包括如果您愿意,可以阅读一些以下行,并且一些错误检查可能也会很好。

    使用.xml文件大小的内容,速度不会成为问题。有时候,简单而笨重比在正常情况下拔头发更好。此外,您确切知道这种方法会得到什么。使用复杂的正则表达式,你基本上试图抓住已知表达式周围的任意文本块,有时会得到奇怪的结果。