Hi,
I am trying to validate (using QRegularExpressionValidator) a URL. It got the regular expression from https://gist.github.com/dperini/729294 and, from what I can tell, it looks good (and it certainly seems to work when I tried using some online regular expression testers). However, my tests using Qt are anything but conclusive. So, could it be that I wrongly 'converted' the regular expression to C++?
Otherwise, worse is the fact that if I try to enter something like "http://uuuuuuuuuuuuuuuuuuuu", then my test application kind of hangs up. In fact, if I run it in debug mode and pause it, I can see that QRegularExpressionValidator::validate() makes an indirect call to pcre16_exec, which itself makes call to match, which itself makes call to match, which itself makes call to match, etc. Could this be a bug in QRegularExpressionValidator or even pcre16_exec?
QRegularExpressionValidatorTest.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QRegularExpressionValidatorTest
TEMPLATE = app
SOURCES += main.cpp
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QRegularExpressionValidatorTest
TEMPLATE = app
SOURCES += main.cpp
To copy to clipboard, switch view to plain text mode
main.cpp:
#include <QApplication>
#include <QDesktopWidget>
#include <QDialog>
#include <QLineEdit>
#include <QRegularExpressionValidator>
#include <QVBoxLayout>
int main(int pArgC, char *pArgV[])
{
dialog->setLayout(dialogLayout);
dialog->setWindowTitle("URL Tester");
// We want to validate a URL, the regular expression of which comes from
// https://gist.github.com/dperini/729294
// It is released under the MIT license and is therefore fine for us to use
"^"
// protocol identifier
"(?:(?:https?|ftp)://)" +
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
"(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
"(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
"|" +
// host name
"(?:(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)" +
// domain name
"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*" +
// TLD identifier
"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,}))" +
")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/[^\\s]*)?" +
"$";
dialogValue->setValidator(new QRegularExpressionValidator(QRegularExpression(urlRegExp, QRegularExpression::CaseInsensitiveOption), dialog));
dialogValue->setMinimumWidth(qApp->desktop()->availableGeometry().width()/5);
dialogLayout->addWidget(dialogValue);
dialogLayout
->setSizeConstraint
(QLayout::SetFixedSize);
dialog->show();
return application.exec();
}
#include <QApplication>
#include <QDesktopWidget>
#include <QDialog>
#include <QLineEdit>
#include <QRegularExpressionValidator>
#include <QVBoxLayout>
int main(int pArgC, char *pArgV[])
{
QApplication application(pArgC, pArgV);
QDialog *dialog = new QDialog();
QVBoxLayout *dialogLayout = new QVBoxLayout(dialog);
dialog->setLayout(dialogLayout);
dialog->setWindowTitle("URL Tester");
// We want to validate a URL, the regular expression of which comes from
// https://gist.github.com/dperini/729294
// It is released under the MIT license and is therefore fine for us to use
QString urlRegExp = QString() +
"^"
// protocol identifier
"(?:(?:https?|ftp)://)" +
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
"(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
"(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
"|" +
// host name
"(?:(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)" +
// domain name
"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*" +
// TLD identifier
"(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,}))" +
")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/[^\\s]*)?" +
"$";
QLineEdit *dialogValue = new QLineEdit(dialog);
dialogValue->setValidator(new QRegularExpressionValidator(QRegularExpression(urlRegExp, QRegularExpression::CaseInsensitiveOption), dialog));
dialogValue->setMinimumWidth(qApp->desktop()->availableGeometry().width()/5);
dialogLayout->addWidget(dialogValue);
dialogLayout->setSizeConstraint(QLayout::SetFixedSize);
dialog->show();
return application.exec();
}
To copy to clipboard, switch view to plain text mode
Bookmarks