【问题标题】:Parsing repeating groups from a string从字符串中解析重复组
【发布时间】:2011-07-05 15:55:18
【问题描述】:

我目前正在接受一个正在分割的字符串

20004=1~^20005=0~^773=~^665=~^453=3~^448=0A~!447=D~!452=1~!~^448=0A~!447=D~!452=17~!~^448=81~!447=D~!452=7~!~^11=1116744Pq2Q~^70=15040024-1~^793=MNL-?--1~^467=37878024-1~^60=20110617-05:57:31~^75=20110616~^768=1~^769=20110616-19:17:00~!770=1~!~^55=7800950~^48=AEP~^22=~^454=0~^460=5~^167=TCKR~^

字符串的构成是 ~^ 划分属性和 ~!标记组。组前面有一个属性,它告诉重复组的数量,例如

453=3~^448=0A~!447=D~!452=1~!~^448=0A~!447=D~!452=17~!~^448=81~!447=D~!452=7~!~^

其中标签 453 表示有 3 个组。

我正在使用这样的解析:

    public Map<Integer, Object> parse(Object target)
{
    String[] elements = ((String) target).split(elementDilimiter);

    Map<Integer, Object> targetFields = new LinkedHashMap<Integer, Object>();

    for(int i=0; i<elements.length; i++)
    {
        String[] attributes = elements[i].split(attributeDelimiter);


        if(attributes.length != 2 || attributes[0].length() == 0 || attributes[1].length() == 0)
        {
            /*throw new ParsingException("Malformed element: " + element + ", expected: tag=value");*/
            continue;
        }
            targetFields.put(Integer.valueOf(attributes[0]), attributes[1]);
    }
    return targetFields;
}

元素分隔符 = ~^ 和属性分隔符 = "="

所以行后:

String[] elements = ((String) target).split(elementDilimiter);

值按如下方式拆分

453=3, 448=0A~!447=D~!452=1~!, 448=0A~!447=D~!452=17~!, 448=81~!447=D~!452=7~!,

然后将它们拆分为相等并使用 tagNo 放置在地图中以返回相关对象。

但是当小组到达时:

String[] attributes = element.split(attributeDelimiter);

由于以下原因,小组没有进一步前进:

attributes.length != 2

但理想情况下,我希望我的实现能够抓取标签 453,实现有 3 个重复组,重复组进入解析器,将它们分隔为 ~!并放置在子地图中。

说实话,当我想到实施时,我开始头晕目眩。

是否有一个简单优雅的解决方案,或者它是从头开始的基本方法。

编辑

是否将 453 定义为始终作为组数的标识符? 是的,组之前的标签只是告诉我会有多少组。我无法控制传入的字符串,或者它的格式将采用上述形式。

您的组代表什么 - 我问这个是因为我认为属性作为组的一部分在一起,但是在您的方法中,您拆分属性而不是组,并且您在属性之前拆分元素? 我拆分了元素,以便可以将它们分隔为 453=3 等,但是后来这个集团业务进来了。所以现在我也必须重写以适应它们。这本质上是我之前的问题,我有可爱的标签值映射到一个对象,可以简单地通过以下方式访问:

targetFields.get(TagNumber);

现在我需要重写以启用对组的可访问性!

我希望这能澄清一些事情

【问题讨论】:

  • 我认为您对问题的解释不够清楚。为什么既需要分隔符模式来分隔组,又需要一个标签来指定有多少组? 453 是否定义为始终作为组数的标识符?你的组代表什么 - 我问这个是因为我认为属性作为组的一部分在一起,但是在你的方法中,你拆分属性而不是组你在元素上拆分 before 属性?这令人困惑;我认为您设置了一些无法自我解释的内容,因此您需要对其进行充分解释。
  • 我对其进行了编辑以回答您的问题,希望它能澄清一些困惑
  • 还是不清楚。在一个地方你说The makeup of the string is such that ~^ divides attributes and ~! marks groups,而在更远的地方你说Element delimiter = ~^ and Attribute delimiter = "="...是哪个?
  • 因为 453=3 等值对左侧的数字是静态的,只有右侧的值发生变化。 ~!指的是具有一组可以重复n次的数字的元素。右侧的数字仅标识右侧的值是我将在新对象中分配的值。我只控制这两个对象之间的映射,而不是结构

标签: java string parsing nested


【解决方案1】:

此代码将解析出组/子组。您可以将 system.print 语句替换为您的地图建筑。但是,您可能需要重新考虑该格式,因为如果您使用像 XML 这样自然支持嵌套的格式,它可能会更清晰

@Test
public void testname() throws Exception {
    parseText("453=3~^448=0A~!447=D~!452=1~!~^448=0A~!447=D~!452=17~!~^448=81~!447=D~!452=7~!~^");
}

private int subgroupLength = 0;

public void parseText(String text) {
    for (String group : text.split("~\\^")) {
        System.out.println("Group");
        parseGroup(group);
    }
}

public void parseGroup(String group) {
    for (String attribute : group.split("~!"))
        parseAttribute(attribute);
}

public void parseAttribute(String attribute) {
    String[] split = attribute.split("=");
    if (split.length != 2)
        return;

    if (split[0].equals("453")) {
        System.out.println("\tSubgroup length " + split[1]);
        subgroupLength = Integer.parseInt(split[1]);
    } else if (subgroupLength > 0) {
        subgroupLength--;
        System.out.println("\t\t" + split[0] + " = " + split[1]);
    } else
        System.out.println("\t" + split[0] + " = " + split[1]);
}

【讨论】:

  • 我需要将它们保存在数据结构中
  • 那么创建一个数据结构...?
【解决方案2】:

分两步使用 String.split。 首先拆分组。之后拆分每个组的属性。

它会解决你的问题。

【讨论】:

    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多