Extract message links with explicit schemes and punctuation boundaries
This commit is contained in:
1 parent
93c0c5bdfc
commit
394ac93dc4
3 files changed
+44
-1
No files matched your search
@@ -0,0 +1,28 @@
|
||||
#include "message_links.h"
|
||||
#include <QRegularExpression>
|
||||
#include <QUrl>
|
||||
|
||||
/* Отделить адрес от текста, сохраняя сбалансированные скобки внутри пути/query. */
|
||||
QVector<MessageLink> messageLinks(const QString& text) {
|
||||
static const QRegularExpression pattern(QStringLiteral(
|
||||
"utun://[A-Za-z0-9+/]+={0,2}|(?i:https?://)[^\\s\\p{Z}\\p{Cc}<>\"'`«»“”‘’]+"));
|
||||
QVector<MessageLink> links;
|
||||
auto matches = pattern.globalMatch(text);
|
||||
while (matches.hasNext()) {
|
||||
const auto match = matches.next();
|
||||
QString url = match.captured();
|
||||
if (!url.startsWith(QStringLiteral("utun://"))) {
|
||||
while (!url.isEmpty()) {
|
||||
const QChar last = url.back();
|
||||
const int closing = QStringLiteral(")]}").indexOf(last);
|
||||
const bool unmatched = closing >= 0 && url.count(last) > url.count(QStringLiteral("([{").at(closing));
|
||||
if (!QStringLiteral(".,;:!?").contains(last) && !unmatched) break;
|
||||
url.chop(1);
|
||||
}
|
||||
const QUrl parsed(url, QUrl::StrictMode);
|
||||
if (!parsed.isValid() || parsed.host().isEmpty()) continue;
|
||||
}
|
||||
links.append({(int)match.capturedStart(), (int)url.length(), url});
|
||||
}
|
||||
return links;
|
||||
}
|
||||
Reference in new issue
Block a user