19 #include <QStringList> 20 #include <QTextBoundaryFinder> 24 if (
string.isEmpty() )
27 switch ( capitalization )
33 return string.toUpper();
36 return string.toLower();
40 QString temp = string;
42 QTextBoundaryFinder wordSplitter( QTextBoundaryFinder::Word,
string.constData(),
string.length(),
nullptr, 0 );
43 QTextBoundaryFinder letterSplitter( QTextBoundaryFinder::Grapheme,
string.constData(),
string.length(),
nullptr, 0 );
45 wordSplitter.setPosition( 0 );
47 while ( ( first && wordSplitter.boundaryReasons() & QTextBoundaryFinder::StartOfItem )
48 || wordSplitter.toNextBoundary() >= 0 )
51 letterSplitter.setPosition( wordSplitter.position() );
52 letterSplitter.toNextBoundary();
53 QString substr =
string.mid( wordSplitter.position(), letterSplitter.position() - wordSplitter.position() );
54 temp.replace( wordSplitter.position(), substr.length(), substr.toUpper() );
66 int length1 = string1.length();
67 int length2 = string2.length();
70 if ( string1.isEmpty() )
74 else if ( string2.isEmpty() )
80 QString s1( caseSensitive ? string1 : string1.toLower() );
81 QString s2( caseSensitive ? string2 : string2.toLower() );
83 const QChar *s1Char = s1.constData();
84 const QChar *s2Char = s2.constData();
87 int commonPrefixLen = 0;
88 while ( length1 > 0 && length2 > 0 && *s1Char == *s2Char )
98 while ( length1 > 0 && length2 > 0 && s1.at( commonPrefixLen + length1 - 1 ) == s2.at( commonPrefixLen + length2 - 1 ) )
109 else if ( length2 == 0 )
115 if ( length1 > length2 )
118 std::swap( length1, length2 );
123 col.fill( 0, length2 + 1 );
124 QVector< int > prevCol;
125 prevCol.reserve( length2 + 1 );
126 for (
int i = 0; i < length2 + 1; ++i )
130 const QChar *s2start = s2Char;
131 for (
int i = 0; i < length1; ++i )
135 for (
int j = 0; j < length2; ++j )
137 col[j + 1] = std::min( std::min( 1 + col[j], 1 + prevCol[1 + j] ), prevCol[j] + ( ( *s1Char == *s2Char ) ? 0 : 1 ) );
143 return prevCol[length2];
148 if ( string1.isEmpty() || string2.isEmpty() )
155 QString s1( caseSensitive ? string1 : string1.toLower() );
156 QString s2( caseSensitive ? string2 : string2.toLower() );
164 int *currentScores =
new int [ s2.length()];
165 int *previousScores =
new int [ s2.length()];
166 int maxCommonLength = 0;
167 int lastMaxBeginIndex = 0;
169 const QChar *s1Char = s1.constData();
170 const QChar *s2Char = s2.constData();
171 const QChar *s2Start = s2Char;
173 for (
int i = 0; i < s1.length(); ++i )
175 for (
int j = 0; j < s2.length(); ++j )
177 if ( *s1Char != *s2Char )
179 currentScores[j] = 0;
183 if ( i == 0 || j == 0 )
185 currentScores[j] = 1;
189 currentScores[j] = 1 + previousScores[j - 1];
192 if ( maxCommonLength < currentScores[j] )
194 maxCommonLength = currentScores[j];
195 lastMaxBeginIndex = i;
200 std::swap( currentScores, previousScores );
204 delete [] currentScores;
205 delete [] previousScores;
206 return string1.mid( lastMaxBeginIndex - maxCommonLength + 1, maxCommonLength );
211 if ( string1.isEmpty() && string2.isEmpty() )
217 if ( string1.length() != string2.length() )
224 QString s1( caseSensitive ? string1 : string1.toLower() );
225 QString s2( caseSensitive ? string2 : string2.toLower() );
234 const QChar *s1Char = s1.constData();
235 const QChar *s2Char = s2.constData();
237 for (
int i = 0; i < string1.length(); ++i )
239 if ( *s1Char != *s2Char )
250 if (
string.isEmpty() )
253 QString tmp =
string.toUpper();
256 QChar *char1 = tmp.data();
257 QChar *char2 = tmp.data();
259 for (
int i = 0; i < tmp.length(); ++i, ++char2 )
261 if ( ( *char2 ).unicode() >= 0x41 && ( *char2 ).unicode() <= 0x5A && ( i == 0 || ( ( *char2 ).unicode() != 0x41 && ( *char2 ).unicode() != 0x45
262 && ( *char2 ).unicode() != 0x48 && ( *char2 ).unicode() != 0x49
263 && ( *char2 ).unicode() != 0x4F && ( *char2 ).unicode() != 0x55
264 && ( *char2 ).unicode() != 0x57 && ( *char2 ).unicode() != 0x59 ) ) )
271 tmp.truncate( outLen );
273 QChar *tmpChar = tmp.data();
275 for (
int i = 1; i < tmp.length(); ++i, ++tmpChar )
277 switch ( ( *tmpChar ).unicode() )
283 tmp.replace( i, 1, QChar( 0x31 ) );
294 tmp.replace( i, 1, QChar( 0x32 ) );
299 tmp.replace( i, 1, QChar( 0x33 ) );
303 tmp.replace( i, 1, QChar( 0x34 ) );
308 tmp.replace( i, 1, QChar( 0x35 ) );
312 tmp.replace( i, 1, QChar( 0x36 ) );
322 for (
int i = 1; i < tmp.length(); ++i, ++char2 )
324 if ( *char2 != *char1 )
333 tmp.truncate( outLen );
334 if ( tmp.length() < 4 )
345 QString converted = string;
349 static QRegExp urlRegEx(
"(\\b(([\\w-]+://?|www[.])[^\\s()<>]+(?:\\([\\w\\d]+\\)|([^!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~\\s]|/))))" );
350 static QRegExp protoRegEx(
"^(?:f|ht)tps?://" );
351 static QRegExp emailRegEx(
"([\\w._%+-]+@[\\w.-]+\\.[A-Za-z]+)" );
355 while ( urlRegEx.indexIn( converted, offset ) != -1 )
358 QString url = urlRegEx.cap( 1 );
359 QString protoUrl = url;
360 if ( protoRegEx.indexIn( protoUrl ) == -1 )
362 protoUrl.prepend(
"http://" );
364 QString anchor = QStringLiteral(
"<a href=\"%1\">%2</a>" ).arg( protoUrl.toHtmlEscaped(), url.toHtmlEscaped() );
365 converted.replace( urlRegEx.pos( 1 ), url.length(), anchor );
366 offset = urlRegEx.pos( 1 ) + anchor.length();
369 while ( emailRegEx.indexIn( converted, offset ) != -1 )
372 QString email = emailRegEx.cap( 1 );
373 QString anchor = QStringLiteral(
"<a href=\"mailto:%1\">%1</a>" ).arg( email.toHtmlEscaped(), email.toHtmlEscaped() );
374 converted.replace( emailRegEx.pos( 1 ), email.length(), anchor );
375 offset = emailRegEx.pos( 1 ) + anchor.length();
386 , mReplacement( replacement )
387 , mCaseSensitive( caseSensitive )
388 , mWholeWordOnly( wholeWordOnly )
390 if ( mWholeWordOnly )
391 mRx = QRegExp( QString(
"\\b%1\\b" ).arg( mMatch ),
392 mCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive );
397 QString result = input;
398 if ( !mWholeWordOnly )
400 return result.replace( mMatch, mReplacement, mCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive );
404 return result.replace( mRx, mReplacement );
411 map.insert( QStringLiteral(
"match" ), mMatch );
412 map.insert( QStringLiteral(
"replace" ), mReplacement );
413 map.insert( QStringLiteral(
"caseSensitive" ), mCaseSensitive ?
"1" :
"0" );
414 map.insert( QStringLiteral(
"wholeWord" ), mWholeWordOnly ?
"1" :
"0" );
421 properties.value( QStringLiteral(
"replace" ) ),
422 properties.value( QStringLiteral(
"caseSensitive" ), QStringLiteral(
"0" ) ) == QLatin1String(
"1" ),
423 properties.value( QStringLiteral(
"wholeWord" ), QStringLiteral(
"0" ) ) == QLatin1String(
"1" ) );
428 QString result = input;
441 QDomElement propEl = doc.createElement( QStringLiteral(
"replacement" ) );
442 QgsStringMap::const_iterator it = props.constBegin();
443 for ( ; it != props.constEnd(); ++it )
445 propEl.setAttribute( it.key(), it.value() );
447 elem.appendChild( propEl );
453 mReplacements.clear();
454 QDomNodeList nodelist = elem.elementsByTagName( QStringLiteral(
"replacement" ) );
455 for (
int i = 0; i < nodelist.count(); i++ )
457 QDomElement replacementElem = nodelist.at( i ).toElement();
458 QDomNamedNodeMap nodeMap = replacementElem.attributes();
461 for (
int j = 0; j < nodeMap.count(); ++j )
463 props.insert( nodeMap.item( j ).nodeName(), nodeMap.item( j ).nodeValue() );
static QString longestCommonSubstring(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the longest common substring between two strings.
A representation of a single string replacement.
QMap< QString, QString > QgsStringMap
static QString soundex(const QString &string)
Returns the Soundex representation of a string.
void writeXml(QDomElement &elem, QDomDocument &doc) const
Writes the collection state to an XML element.
static QgsStringReplacement fromProperties(const QgsStringMap &properties)
Creates a new QgsStringReplacement from an encoded properties map.
static QString capitalize(const QString &string, Capitalization capitalization)
Converts a string by applying capitalization rules to the string.
static int levenshteinDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Levenshtein edit distance between two strings.
Convert just the first letter of each word to uppercase, leave the rest untouched.
Convert all characters to uppercase.
Capitalization
Capitalization options.
QgsStringMap properties() const
Returns a map of the replacement properties.
QString process(const QString &input) const
Processes a given input string, applying any valid replacements which should be made.
Mixed case, ie no change.
Convert all characters to lowercase.
void readXml(const QDomElement &elem)
Reads the collection state from an XML element.
QString process(const QString &input) const
Processes a given input string, applying any valid replacements which should be made using QgsStringR...
QgsStringReplacement(const QString &match, const QString &replacement, bool caseSensitive=false, bool wholeWordOnly=false)
Constructor for QgsStringReplacement.
static QString insertLinks(const QString &string, bool *foundLinks=nullptr)
Returns a string with any URL (e.g., http(s)/ftp) and mailto: text converted to valid HTML <a ...
static int hammingDistance(const QString &string1, const QString &string2, bool caseSensitive=false)
Returns the Hamming distance between two strings.