Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QregExp for IPv4 address (xxx.xxx.xxx.xxx)



  • In my Application, I have log window (subclassed QPlainTextEdit with syntax highlighting, based on Sytnax Highlighter Example. I've implemented three types of log info entry:

    • [INFO] - Info type log entry begins with QString containing "[INFO]"

    • [WARNING] - Info type log entry begins with QString containing "[WARNING]"

    • [ERROR] - Info type log entry begins with QString containing "[ERROR]"

    Based on log info type, the color of entry is applied - blue (INFO), yellow (WARNING) and red (ERROR). This all works perfectly. Now, the log entry contents continues with time stamp, as you can see from following class static method:

    const QString UeLogWindow::ueCreateLogEntry(const quint8& logEntryType,
                                                const QString& logText)
    {
        // TODO improve logEntryType - work with enum
        // TODO remove appended ip address
        QString result=QString();
        QString timeStamp=QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss:zzz");
    
        switch(logEntryType)
        {
            case 0:
            {
                result=tr("[INFO]");
    
                break;
            }   // case
    
            case 1:
            {
                result=tr("[WARNING]");
    
                break;
            }   // case
    
            case 2:
            {
                result=tr("[ERROR]");
    
                break;
            }   // case
    
            default:
            {
                break;
            }   // default
        }   // switch
    
        result.append(" ")
              .append(timeStamp)
              .append(" ")
              .append(logText)
              .append(" ")
              .append("192.168.100.1"); // only for test purposes to see if  highlighting is working
    
        return result;
    }   // ueCreateLogEntry
    

    Now, here are my sytnax highlighting rules:

    UeLogWindowTextHighlighter::UeLogWindowTextHighlighter(QTextDocument* const parent)
        : QSyntaxHighlighter (parent)
    {
        UeHighlightRule ruleInfo;
        UeHighlightRule ruleWarning;
        UeHighlightRule ruleError;
        UeHighlightRule ruleIPv4Address;
    
        QTextCharFormat ruleInfoFormat;
        QTextCharFormat ruleWarningFormat;
        QTextCharFormat ruleErrorFormat;
        QTextCharFormat ruleIPv4AddressFormat;
    
        ruleInfoFormat.setForeground(Qt::darkBlue);
        ruleInfoFormat.setFontWeight(QFont::ExtraLight);
        ruleInfo.pattern=QRegExp("^\[INFO\].*");
        ruleInfo.format=ruleInfoFormat;
    
        ruleWarningFormat.setForeground(Qt::darkYellow);
        ruleWarningFormat.setFontWeight(QFont::Normal);
        ruleWarning.pattern=QRegExp("^\[WARNING\].*");
        ruleWarning.format=ruleWarningFormat;
    
        ruleErrorFormat.setForeground(Qt::darkRed);
        ruleErrorFormat.setFontWeight(QFont::ExtraBold);
        ruleError.pattern=QRegExp("^\[ERROR\].*");
        ruleError.format=ruleErrorFormat;
    
        ruleIPv4AddressFormat.setFontWeight(QFont::ExtraBold);
        ruleIPv4Address.pattern=QRegExp("(\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})");
        ruleIPv4Address.format=ruleIPv4AddressFormat;
    
        m_ueHighlightRules.append(ruleInfo);
        m_ueHighlightRules.append(ruleWarning);
        m_ueHighlightRules.append(ruleError);
        m_ueHighlightRules.append(ruleIPv4Address);
    }   // constructor
    

    Now, ruleIPv4Address also affects my timestamp beside ip address itself in log entry:
    Screenshot
    How do I change regular expression to avoid affecting my timestamp?



  • I think you have to escape the point character because it's treated as "any character" in a reg exp. (prefix it with an escaped backslash: QRegExp("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})");)



  • . should be escaped
    "(\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})" should become "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"

    On a separate note, if you are using Qt5, you should use QregularExpression instead of QRegExp

    Edit:
    @micland was faster on the draw

    Edit2:
    I think your internationalisation will break the syntax highlight (e.g. if WARNING becomes ATTENTION in French the regular expression will not match anymore)

    Edit3:
    Your regexp will match invalid IP addresses (500.1.1.0 should not match) see here: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html for the correct pattern



  • @VRonin said:

    . should be escaped
    "(\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3})" should become "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"

    On a separate note, if you are using Qt5, you should use QregularExpression instead of QRegExp

    Edit:
    @micland was faster on the draw

    Edit2:
    I think your internationalisation will break the syntax highlight (e.g. if WARNING becomes ATTENTION in French the regular expression will not match anymore)

    Edit3:
    Your regexp will match invalid IP addresses (500.1.1.0 should not match) see here: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html for the correct pattern

    You have strong good point by commenting break of syntax highlight because of internationalisation, are there any solutions for current code?



  • @MarkoSan said:

    are there any solutions for current code?

    either you enclose the RegExp pattern in tr() and trust the translator to do the right thing or you declare

    private:
    const QString logTags[3];
    

    then in the constructor add the initialisation

    UeLogWindow::UeLogWindow(QWidget parent)
    :  \\ ... other inits
    , logTags{tr("[INFO]"),tr("[WARNING]"),tr("[ERROR]")}
    

    (if you don't have access to C++11 functionality you should not declare const and initialise the members with the usual [] operator)

    this also simplifies a lot the switch(logEntryType) part

    to use them in the regular expression you then just have to call QRegularExpression::escape(). for example, ruleError.pattern=QRegExp("^\[ERROR\].*"); would become

    ruleError.pattern=QRegExp("^"+QRegExp::escape(logEntryType[2])+".*");
    

    Again, here I used QRegExp but you should REALLY use QRegularExpression especially if you expect a big number of matches


Log in to reply