3

したがって、org.apache.commons.lang3.text には StrSubstitutor というクラスがあり、次のようなマップを取り込むことができます。

Map<String, String> params = new HashMap<String, String>();
params.put("name","Vivek");
params.put("id","900");
params.put("somethingelse","blah");

そして、次のようなテンプレート文字列:

    <data>
       <id>${id}</id>
       <name>${name}</name>
       <something>${somethingelse}</something>
    </data>

次のような出力文字列を生成します。

   <data>
       <id>900</id>
       <name>Vivek</name>
       <something>blah</something>
   </data>

私が望むのは反対です。出力文字列とテンプレートを取得して、テンプレート変数をキーとして、文字列内の対応する値を値としてマップに入力する方法はありますか?

PS - 使用する文字列は必ずしも XML であるとは限りません。これは単なる例です。

EDIT:変数名とタグ名が同じだったので、混乱している人もいると思います。タグは説明のためのものであり、問​​題とは関係ありません。私が気になっているのは ${} 内の変数です。意味を示すために別のタグを追加しました。

4

2 に答える 2

0

パターンを使用してフォーマット文字列を正規表現に変換し、この正規表現を使用して入力文字列を進行させることができます。クラスの例を以下に示します。

public final class FormatReader {

    private final Pattern formatPattern;
    private final List<String> names;

    private FormatReader(
            final Pattern formatPattern,
            final List<String> names) {
        ////
        this.formatPattern = formatPattern;
        this.names = names;
    }

    public static FormatReader of(
            final String prefix,
            final String suffix,
            final String format) {
        ////
        return of(prefix, suffix, format, true);
    }

    public static FormatReader of(
            final String prefix,
            final String suffix,
            final String format,
            final boolean allowSurroundingWhitespace) {
        ////
        // This method is somewhat ugly...
        final List<String> names = new ArrayList<>();
        final StringBuilder sb = new StringBuilder("(?m)");
        boolean skip = allowSurroundingWhitespace;
        if (skip)
            sb.append("\\s*");
        for (int i = 0, last = 0, prefixLength = prefix.length(), suffixLength = suffix.length();;) {
            if (i == format.length()) {
                if (!skip)
                    sb.append(Pattern.quote(format.substring(last)));
                break;
            }
            if (format.startsWith(prefix, i)) {
                skip = true;
                sb.append(Pattern.quote(format.substring(last, i))).append("(.+)");

                final int off = i + prefixLength;
                names.add(format.substring(off, i = format.indexOf(suffix, off)));
                i += suffixLength;
                continue;
            }
            if (Character.isWhitespace(format.charAt(i))) {
                if (!skip) {
                    skip = true;
                    // Replace '\s*' with '\s+' if at least one whitespace has to be present
                    sb.append(Pattern.quote(format.substring(last, i))).append("\\s*");
                }
            } else if (skip) {
                last = i;
                skip = false;
            }
            i++;
        }
        if (!skip && allowSurroundingWhitespace)
            sb.append("\\s*");
        return new FormatReader(Pattern.compile(sb.toString()), names);
    }

    public Map<String, String> toMap(
            final String input) {
        ////
        final Matcher m = formatPattern.matcher(input);
        if (!m.matches())
            throw new IllegalArgumentException("Argument does not match format");
        final Map<String, String> map = new HashMap<>();
        for (int i = 0; i < m.groupCount();)
            map.put(names.get(i), m.group(++i));
        return map;
    }

    public static void main(
            final String[] args) {
        ////
        final FormatReader r = of("${", "}", ""
                + "   <data>\n"
                + "       <id>${id}</id>\n"
                + "       <name>${name}</name>\n"
                + "   </data>");
        final String s = ""
                + "      <data>\n"
                + "        <id>900</id>           "
                + "    <name>Vivek</name>\n"
                + "  </data>    ";
        // The created pattern (accepts any count of whitespace):
        //                             'id'                     'name'
        // (?m)\s*\Q<data>\E\s*\Q<id>\E(.+)\Q</id>\E\s*\Q<name>\E(.+)\Q</name>\E\s*\Q</data>\E\s*
        System.out.println(r.toMap(s)); // {name=Vivek, id=900}
    }
}
于 2016-10-02T02:34:46.727 に答える