文档中的QSyntaxHighlighter多行注释未正确显示

时间:2014-10-30 10:40:38

标签: regex qt qt4 syntax-highlighting

参考QT官方网站提供的Syntax Highlighter Example,我试图在我的应用程序中实现(实际上你可以调用复制粘贴)相同的多行注释逻辑。作为参考,这是多行注释突出显示的代码:

构造函数内部:

quotationFormat.setForeground(QColor(164, 14, 14));
rule.pattern = QRegExp("\".*\"");
rule.format = quotationFormat;
highlightingRules.append(rule);

charFormat.setForeground(QColor(164, 14, 14));
rule.pattern = QRegExp("\'.*\'");
rule.format = charFormat;
highlightingRules.append(rule);

singleLineCommentFormat.setForeground(Qt::darkGreen);
rule.pattern = QRegExp("//[^\n]*");
rule.format = singleLineCommentFormat;
highlightingRules.append(rule);
multiLineCommentFormat.setForeground(Qt::darkGreen);

commentStartExpression = QRegExp("/\\*");
commentEndExpression = QRegExp("\\*/");

在highlightBlock()函数内:

foreach (const HighlightingRule &rule, highlightingRules) {
    QRegExp expression(rule.pattern);
    int index = expression.indexIn(text);
    while (index >= 0) {
        int length = expression.matchedLength();
        setFormat(index, length, rule.format);
        index = expression.indexIn(text, index + length);
    }
}
setCurrentBlockState(0);

int startIndex = 0;
if (previousBlockState() != 1)
    startIndex = commentStartExpression.indexIn(text);

while (startIndex >= 0) {
    int endIndex = commentEndExpression.indexIn(text, startIndex);
    int commentLength;
    if (endIndex == -1) {
        setCurrentBlockState(1);
        commentLength = text.length() - startIndex;
    } else {
        commentLength = endIndex - startIndex
                        + commentEndExpression.matchedLength();
    }
    setFormat(startIndex, commentLength, multiLineCommentFormat);
    startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
}

但是当/ *出现在引号内时,我仍然面临着问题。它以多行注释颜色(绿色)显示直到结束(/*.png" ] })请参阅以下示例文档内容以供参考:

{
    "code": [
        "./Code/Main.js"
    ],

    "textures": [
        "./Content/*.png"
    ]
}

我不是正则表达的主人,但我想正则表达式有问题。

1 个答案:

答案 0 :(得分:2)

通过一些运气和努力,我找到了一种解决方法(仍然不会涵盖所有情况)

    int MySyntaxHighlighter::getCommentStartIndex(const QString &text, const int offset)
    {
        int startIndex = -1;

        qDebug() << "offset: " << offset;

        if(text.length() > 1 && offset < (text.length() - 1)) {

            int commentStartIndex = commentStartExpression.indexIn(text, offset);
            qDebug() << "commentStartIndex: " << commentStartIndex;

            QRegExp quotationExpression(quotationRule.pattern);

            int quotationStartIndex = quotationExpression.indexIn(text, offset);
            qDebug() << "quotationStartIndex: " << quotationStartIndex;

            if (quotationStartIndex >= 0) {

                int quotationLength = quotationExpression.matchedLength();
                qDebug() << "quotationLength: " << quotationLength;

                if(commentStartIndex > quotationStartIndex &&
                        commentStartIndex < (quotationStartIndex + quotationLength)) {

                    startIndex = getCommentStartIndex(text, (commentStartIndex + 2));
                } else {
                    startIndex = commentStartIndex;
                }
            } else if(commentStartIndex >= 0) {
                startIndex = commentStartIndex;
            } else {
                startIndex = -1;
            }
        }

        qDebug() << "startIndex: " << startIndex;

        return startIndex;
    }

    void MySyntaxHighlighter::highlightBlock(const QString &text)
    {
        setCurrentBlockState(0);

        qDebug() << "text: " << text;
        qDebug() << "previousBlockState(): " << previousBlockState();

        int startIndex = 0;
        if (previousBlockState() != 1) {
//        startIndex = commentEndExpression.indexIn(text);
            startIndex = getCommentStartIndex(text, 0);
        }

        while (startIndex >= 0) {
            int endIndex = commentEndExpression.indexIn(text, startIndex);
            int commentLength;
            if (endIndex == -1) {
                setCurrentBlockState(1);
                commentLength = text.length() - startIndex;
            } else {
                commentLength = endIndex - startIndex
                                + commentEndExpression.matchedLength();
            }
            setFormat(startIndex, commentLength, multiLineCommentFormat);

    //        startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
            startIndex = getCommentStartIndex(text, startIndex + commentLength);
        }    
    }

如果有人找到更好的解决方案,请与我分享。