JTextPane中的着色正则表达式单词模式不能着色尾随分隔符



感谢这个名单上的好人,我就快成功了。我只是需要最后一点的帮助。

我有一个JTextPane,我匹配某些单词模式并将其颜色更改为红色。任何以pipe/开方括号开始,以闭方括号/pipe结束的单词或短语,如|[this]|,将与以下正则表达式"(\|\[[^\]]*\])"匹配。

这个方法99%有效,但是它不会将尾线染成红色。如果我试图将其包含在正则表达式中,通过在末尾添加\|,它无法匹配任何内容。

这是我的代码。

在调用类的按钮中,我现在发送一个带有分隔符的字符串:

private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {                                          
    JFrame Escapedframe = new JFrame("Skipppy Cars word changer");
    Escapedframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    JTextPane SkippytextPane = new JTextPane();
    SkippytextPane.setDocument(new ElementHighlight());
    SkippytextPane.setText("You should try the |[new model]| car, the |[Skippy 2000]|. The Skippy 2000 comes standard with all the |[features]| of the Bippy 3000, at half the price. You can buy one today at your |[athorized Skippy/Bippy]| dealer.");
    Escapedframe.add(SkippytextPane);
    Escapedframe.setSize(500,400);
    Escapedframe.setLocationRelativeTo(null);
    Escapedframe.setVisible(true);
}  

然后设置:

private int pipeCharEnd (String Xtext, int index) {
    while (--index >= 0) {
        if (String.valueOf(Xtext.charAt(index)).matches("\|")) {
            break;
        }
    }
    return index;
}
private int pipeCharStart (String Xtext, int index) {
    while (index < Xtext.length()) {
        if (String.valueOf(Xtext.charAt(index)).matches("\|")) {
            break;
        }
        index++;
    }
    return index;
}

最后是class:

class ElementHighlight extends DefaultStyledDocument {
  private final  MutableAttributeSet XRED = new SimpleAttributeSet();
  final StyleContext myProtected = StyleContext.getDefaultStyleContext();
  final AttributeSet attR = myProtected.addAttribute(myProtected.getEmptySet(), StyleConstants.Foreground, Color.RED);
  final AttributeSet attB = myProtected.addAttribute(myProtected.getEmptySet(), StyleConstants.Foreground, Color.BLUE);
@Override
  public void insertString (int offset, String Pstr, AttributeSet RedBlue) throws BadLocationException
  {
   super.insertString(offset, Pstr, RedBlue);
   String text = getText(0, getLength());
   int pre = pipeCharEnd(text, offset);
   if (pre < 0) pre = 0;
   int post = pipeCharStart(text, offset + Pstr.length());
   int prewords = pre;
   int postwords = pre;
   while (postwords <= post) {
                if (postwords == post || String.valueOf(text.charAt(postwords)).matches("\|")) {
                    if (text.substring(prewords, postwords).matches("(\|\[[^\]]*\])"))
                        setCharacterAttributes(prewords, postwords - prewords, attR, false);
                    else
                        setCharacterAttributes(prewords, postwords - prewords, attB, false);
                    prewords = postwords;
                }
                postwords++;
            }

  }

 }

每个分隔的短语都变成红色,正如预期的那样,除了每种情况下的尾管仍然是蓝色。

正如我所说的,在这个名单上的好人的帮助下,我走了这么远。如果有人能教我如何给分隔符后面的管道上色,我将不胜感激。

既然输入了以下if条件:

text.substring(prewords, postwords).matches("(\|\[[^\]]*\])")

…表示索引prewords和索引postword -1(包括)之间的子String匹配(\|\[[^\]]*\])。这个正则表达式查找:

  • a |后接
  • a [后接
  • ]外的任意字符序列,后面跟着
  • a ] .

那么,考虑这个示例String:

0123|[6789012345678]|12345

正则表达式将匹配|[6789012345678](而不是末尾的|)。因此,我们将进入if条件,prewords的值为4, postwords的值为20

prewords = 4, postwords = 20
    v               v
0123|[6789012345678]|12345

如果你这样做:

setCharacterAttributes(prewords, postwords - prewords, attR, false);

…那么你就是在声明:

  • postwords - prewords字符
  • 从索引prewords开始
  • 变为红色

…这是索引420-4(16)个字符,在我们的示例String中表示以下子String: |[6789012345678](仅16个字符)。

如果你还想设置一个字符的颜色…只需将+1添加到方法调用中!

即:

//                                                   here
//                                                     v
setCharacterAttributes(prewords, postwords - prewords +1, attR, false);

最新更新