0

正規表現を使用してJavaのテキストを解析しています

myAttribute="some text" のような文字列があり、このように解析しています

Pattern attributePattern = Pattern.compile("[a-z0-9]*=\"[^\"]*\"");

ただし、属性値に二重引用符を使用したい人もいると思います。

例: myAttribute="some text with a double quote \" here"

これを処理するために正規表現を調整するにはどうすればよいですか

これが属性を解析する私のコードです

private HashMap<String, String> findAttributes(String macroAttributes) {
    Matcher matcher = attributePattern.matcher(macroAttributes);
    HashMap<String, String> map = new HashMap<String, String>();
    while (matcher.find()) {
        String attribute = macroAttributes.substring(matcher.start(), matcher.end());
        int equalsIndex = attribute.indexOf("=");
        String attrName = attribute.substring(0, equalsIndex);
        String attrValue = attribute.substring(equalsIndex+2, attribute.length()-1);
        map.put(attrName, attrValue);
    }
    return map;
}

findAttributes("my=\"some text with a double quote \\\" here\"");

サイズ 1 のマップを返す必要があります。値は、二重引用符 \" を含むテキストにする必要があります。

4

2 に答える 2

1

ネガティブルックビハインドを使用して、引用符の前にバックスラッシュがあるかどうかを確認できますが、バックスラッシュ自体もエスケープできる場合は失敗します。

myAttribute="some text with a trailing backslash \\"

それが可能であれば、次のようなことを試してください。

Pattern.compile("[a-zA-Z0-9]+=\"([^\"\\\\]|\\\\[\"\\\\])*\"")

簡単な説明:

[a-zA-Z0-9]+     # the key
=                # a literal '='
\"               # a literal '"'
(                # start group
  [^\"\\\\]      #   any char except '\' and '"'
  |              #   OR
  \\\\[\"\\\\]   # either '\\' or '\"'
)*               # end group and repeat zero or more times
\"               # a literal '"'

簡単なデモ:

public class Main {

    private static HashMap<String, String> findAttributes(Pattern p, String macroAttributes) {
        Matcher matcher = p.matcher(macroAttributes);
        HashMap<String, String> map = new HashMap<String, String>();
        while (matcher.find()) {
            map.put(matcher.group(1), matcher.group(2));
        }
        return map;
    }

    public static void main(String[] args) {
        final String text = "my=\"some text with a double quote \\\" here\"";
        System.out.println(findAttributes(Pattern.compile("([a-z0-9]+)=\"((?:[^\"\\\\]|\\\\[\"\\\\])*)\""), text));
        System.out.println(findAttributes(Pattern.compile("([a-z0-9]*)=\"((?:[^\"]*|(?<=\\\\)\")*)\""), text));
    }
}

印刷されます:

{my=二重引用符付きのテキスト\"ここ}
{my=二重引用符付きのテキスト\}
于 2013-03-04T10:47:28.393 に答える
1

そのために、代替と肯定的な後読みアサーションを使用できます

Pattern attributePattern = Pattern.compile("[a-z0-9]*=\"(?:[^\"]*|(?<=\\\\)\")*\"");

(?:[^\"]*|(?<=\\\\)\")*[^\"]*またはのいずれかに一致する代替です。(?<=\\\\)\"

(?<=\\\\)\"は " に一致しますが、前にバックラッシュがある場合のみです。

于 2013-03-04T10:10:03.263 に答える