我想在jEditorPane中执行语法高亮显示。它允许我执行单行语法高亮显示,但如果XML标记被拆分为两行或更多行,则它不起作用。下面是我用于语法突出显示的代码。帮助我解决这个问题。感谢.....
public class XmlView extends PlainView {
private static HashMap<Pattern, Color> patternColors;
private static String TAG_PATTERN = "(</?[A-Za-z\\-_0-9]*)\\s?>?";
private static String TAG_END_PATTERN = "(/>)";
private static String TAG_ATTRIBUTE_PATTERN = "\\s(\\w*)\\=";
private static String TAG_ATTRIBUTE_VALUE = "[a-z\\-]*\\=(\"[^\"]*\")";
private static String TAG_COMMENT = "(<\\!--[\\w * \\S]*-->)";
private static String TAG_CDATA = "(<\\!\\[CDATA\\[.*\\]\\]>)";
static {
// NOTE: the order is important!
patternColors = new LinkedHashMap<Pattern, Color>();
patternColors.put(Pattern.compile(TAG_PATTERN), new Color(163, 21, 21));
patternColors.put(Pattern.compile(TAG_CDATA), Color.GRAY);
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_PATTERN), new Color(127, 0, 127));
patternColors.put(Pattern.compile(TAG_END_PATTERN), new Color(63, 127, 127));
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_VALUE), new Color(42, 0, 255));
patternColors.put(Pattern.compile(TAG_COMMENT), new Color(0, 128, 0));
}
public XmlView(Element element) {
super(element);
// Set tabsize to 4 (instead of the default 8)
getDocument().putProperty(PlainDocument.tabSizeAttribute, 4);
}
@Override
protected int drawUnselectedText(Graphics graphics, int x, int y, int p0,
int p1) throws BadLocationException {
Document doc = getDocument();
String text = doc.getText(p0, p1 - p0);
Segment segment = getLineBuffer();
SortedMap<Integer, Integer> startMap = new TreeMap<Integer, Integer>();
SortedMap<Integer, Color> colorMap = new TreeMap<Integer, Color>();
// Match all regexes on this snippet, store positions
for (Map.Entry<Pattern, Color> entry : patternColors.entrySet()) {
Matcher matcher = entry.getKey().matcher(text);
while (matcher.find()) {
startMap.put(matcher.start(1), matcher.end());
colorMap.put(matcher.start(1), entry.getValue());
}
}
// TODO: check the map for overlapping parts
int i = 0;
// Colour the parts
for (Map.Entry<Integer, Integer> entry : startMap.entrySet()) {
int start = entry.getKey();
int end = entry.getValue();
if (i < start) {
graphics.setColor(Color.black);
doc.getText(p0 + i, start - i, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
}
graphics.setColor(colorMap.get(start));
i = end;
doc.getText(p0 + start, i - start, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, start);
}
// Paint possible remaining text black
if (i < text.length()) {
graphics.setColor(Color.black);
doc.getText(p0 + i, text.length() - i, segment);
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
}
return x;
}
}
答案 0 :(得分:3)
标签,评论和CDATA部分的正则表达式需要分为两部分:
Pattern TAG_START = Pattern.compile("</?[\\w-]+");
Pattern TAG_END = Pattern.compile("/?>");
Pattern COMMENT_START = Pattern.compile("<!--");
Pattern COMMENT_END = Pattern.compile("-->");
Pattern CDATA_START = Pattern.compile("<\\[CDATA\\[");
Pattern CDATA_END = Pattern.compile("\\]\\]>");
每当你对其中一个*_START
模式进行匹配时,就会设置一个标志,表明你处于不同的模式。例如,TAG_START
上的匹配会使您处于TAG模式,这意味着您在标记内。每种模式都有自己的一组模式,有些模式与其他模式共享,有些模式特定。
例如,在默认模式下,您可以查找上面列出的*_START
模式,以及其他适合的模式。在TAG模式下,您可以查找属性/值对以及TAG_END
模式,这些模式在标记之外没有意义。并且您始终首先查找TAG_END
模式 ,以确保您确实仍在标记中。 (或者以*_END
模式适用于您所处的模式。)
由于模式可以跨行界限持续存在,这意味着您必须在绘制一行和绘制下一行(复杂)之间保存一些状态,或者每次绘制一条线(慢)时扫描整个文档。无论采用哪种方法,性能在很大程度上取决于正则表达式的质量。例如,你的正则表达式:
"(<\\!--[\\w * \\S]*-->)"
...最初会消耗从<!--
到文档末尾的所有内容,只需要在很长的路上进行回溯。此外,如果有两个或更多注释,它将从第一个的开头到最后一个的结尾匹配。出于这两个原因,我会这样写:
"<!--[^-]*+(?>-(?!->))*+-->"
注意使用所有格量词(*+
)和原子组((?>...)
)。从正确的角度来看,它们不是必需的,但它们使正则表达式更有效率,这在这个项目中尤为重要。
还有一件事:如果你打算使用find()
,你还应该将\G
(最后一个匹配的锚点)添加到每个正则表达式的开头,就像弗里德在this regex from his book做了。
答案 1 :(得分:0)
您可能需要使用Pattern.MULTILINE标志吗?
e.g。
Pattern.compile(TAG_PATTERN, Pattern.MULTILINE)