-1

您好,我有一个无法解决的问题。A 已经从 jar 清单中以 String 的形式导出了 pacakges,我想把它放在 Map 中,其中 key 是包的名称,其余信息在value中。你会说这很简单,但让我们告诉你我到底想做什么。我有一根弦,我从中取一小块

 aQute.bnd.annotation;version="1.43.1",aQute.bnd.annotati
 on.component;version="1.43.1",aQute.bnd.annotation.metatype;version="1.
 43.1",aQute.bnd.ant;uses:="aQute.service.reporter,org.apache.tools.ant,
 org.apache.tools.ant.taskdefs,org.apache.tools.ant.types";version="0.0.
 0",aQute.bnd.build;version="2.1.0";uses:="aQute.bnd.maven.support,aQute
 .bnd.osgi,aQute.bnd.service,aQute.bnd.service.action,aQute.bnd.version,
 aQute.service.reporter",aQute.bnd.build.model;version="2.3";uses:="aQut
 e.bnd.build.model.clauses,aQute.bnd.properties,aQute.bnd.version,org.os
 gi.resource",aQute.bnd.build.model.clauses;version=2;uses:="aQute.bnd.h
 eader",aQute.bnd.build.model.conversions;uses:="aQute.bnd.build.model,a
 Qute.bnd.build.model.clauses,aQute.bnd.header,aQute.libg.tuple,org.osgi
 .resource";version="0.0.0"

如果我在键中将它拆分为逗号(,),则会出现错误的和平,因为我们有

aQute.bnd.ant;uses:="aQute.service.reporter,org.apache.tools.ant,
 org.apache.tools.ant.taskdefs,org.apache.tools.ant.types";version="0.0.
 0"

where 在uses子句中,我们也用逗号分隔依赖包的名称。所以上面的行必须在我的输出映射中:

Key: aQute.bnd.ant
Value: uses:="aQute.service.reporter,org.apache.tools.ant,
 org.apache.tools.ant.taskdefs,org.apache.tools.ant.types";version="0.0.
 0"

那么使用哪些字符串方法或正则表达式来完成我的工作?

4

2 回答 2

1
//split at , only if it's not within ""
String[] packages=input.split(",(?=([^\"]*\"[^\"]*\")+[^\"]*$)");
for(String pack:packages)
{
    String[] output=pack.split("(?=uses:=)");
    output[0];//key
    if(output.length==2)//incase if there's no value
    output[1];//value
}

编辑

(?=uses:=)是一个前瞻,它将在后面的位置匹配uses:=..现在我们可以用作uses:=正则表达式,但那会吃掉uses:=......为了避免它,我们使用零宽度前瞻

于 2013-10-26T10:46:22.190 回答
1

有时长路是最简单的方法:

public static Map<String, String> parse(String s) {
    Map<String, String> allPackageInfo = new HashMap<>();

    CharacterIterator i = new StringCharacterIterator(s);
    char c = i.first();
    while (c != CharacterIterator.DONE) {
        StringBuilder packageName = new StringBuilder();
        while (c != ';' && c != CharacterIterator.DONE) {
            packageName.append(c);
            c = i.next();
        }

        if (c == ';') {
            c = i.next();
        }

        StringBuilder packageInfo = new StringBuilder();
        while (c != ',' && c != CharacterIterator.DONE) {
            if (c == '"') {
                do {
                    packageInfo.append(c);
                    c = i.next();
                } while (c != '"');
            }
            packageInfo.append(c);
            c = i.next();
        }

        if (c == ',') {
            c = i.next();
        }

        allPackageInfo.put(packageName.toString(), packageInfo.toString());
    }

    return allPackageInfo;
}
于 2013-10-26T13:31:27.050 回答