mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Add QgsStringUtils.containsByWord method
Given a candidate string, returns true if the candidate contains all the individual words from another string, regardless of their order.
This commit is contained in:
parent
eab9636fa5
commit
0fff1f16b4
@ -18,5 +18,6 @@ try:
|
||||
QgsStringUtils.htmlToMarkdown = staticmethod(QgsStringUtils.htmlToMarkdown)
|
||||
QgsStringUtils.qRegExpEscape = staticmethod(QgsStringUtils.qRegExpEscape)
|
||||
QgsStringUtils.truncateMiddleOfString = staticmethod(QgsStringUtils.truncateMiddleOfString)
|
||||
QgsStringUtils.containsByWord = staticmethod(QgsStringUtils.containsByWord)
|
||||
except (NameError, AttributeError):
|
||||
pass
|
||||
|
||||
@ -328,6 +328,19 @@ will be truncated by removing characters from the middle of the string
|
||||
and replacing them with a horizontal ellipsis character.
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
static bool containsByWord( const QString &candidate, const QString &words, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive );
|
||||
%Docstring
|
||||
Given a ``candidate`` string, returns ``True`` if the ``candidate`` contains
|
||||
all the individual words from another string, regardless of their order.
|
||||
|
||||
.. note::
|
||||
|
||||
The search does NOT need to match whole words in the ``candidate`` string,
|
||||
so eg a candidate string of "Worldmap_Winkel_II" will return ``True`` for ``words`` "winkle world"
|
||||
|
||||
.. versionadded:: 3.42
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
@ -18,5 +18,6 @@ try:
|
||||
QgsStringUtils.htmlToMarkdown = staticmethod(QgsStringUtils.htmlToMarkdown)
|
||||
QgsStringUtils.qRegExpEscape = staticmethod(QgsStringUtils.qRegExpEscape)
|
||||
QgsStringUtils.truncateMiddleOfString = staticmethod(QgsStringUtils.truncateMiddleOfString)
|
||||
QgsStringUtils.containsByWord = staticmethod(QgsStringUtils.containsByWord)
|
||||
except (NameError, AttributeError):
|
||||
pass
|
||||
|
||||
@ -328,6 +328,19 @@ will be truncated by removing characters from the middle of the string
|
||||
and replacing them with a horizontal ellipsis character.
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
static bool containsByWord( const QString &candidate, const QString &words, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive );
|
||||
%Docstring
|
||||
Given a ``candidate`` string, returns ``True`` if the ``candidate`` contains
|
||||
all the individual words from another string, regardless of their order.
|
||||
|
||||
.. note::
|
||||
|
||||
The search does NOT need to match whole words in the ``candidate`` string,
|
||||
so eg a candidate string of "Worldmap_Winkel_II" will return ``True`` for ``words`` "winkle world"
|
||||
|
||||
.. versionadded:: 3.42
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
@ -745,6 +745,23 @@ QString QgsStringUtils::truncateMiddleOfString( const QString &string, int maxLe
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QgsStringUtils::containsByWord( const QString &candidate, const QString &words, Qt::CaseSensitivity sensitivity )
|
||||
{
|
||||
if ( candidate.trimmed().isEmpty() )
|
||||
return false;
|
||||
|
||||
const thread_local QRegularExpression rxWhitespace( QStringLiteral( "\\s+" ) );
|
||||
const QStringList parts = words.split( rxWhitespace, Qt::SkipEmptyParts );
|
||||
if ( parts.empty() )
|
||||
return false;
|
||||
for ( const QString &word : parts )
|
||||
{
|
||||
if ( !candidate.contains( word, sensitivity ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsStringReplacement::QgsStringReplacement( const QString &match, const QString &replacement, bool caseSensitive, bool wholeWordOnly )
|
||||
: mMatch( match )
|
||||
, mReplacement( replacement )
|
||||
|
||||
@ -317,6 +317,17 @@ class CORE_EXPORT QgsStringUtils
|
||||
*/
|
||||
static QString truncateMiddleOfString( const QString &string, int maxLength );
|
||||
|
||||
/**
|
||||
* Given a \a candidate string, returns TRUE if the \a candidate contains
|
||||
* all the individual words from another string, regardless of their order.
|
||||
*
|
||||
* \note The search does NOT need to match whole words in the \a candidate string,
|
||||
* so eg a candidate string of "Worldmap_Winkel_II" will return TRUE for \a words "winkle world"
|
||||
*
|
||||
* \since QGIS 3.42
|
||||
*/
|
||||
static bool containsByWord( const QString &candidate, const QString &words, Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive );
|
||||
|
||||
};
|
||||
|
||||
#endif //QGSSTRINGUTILS_H
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "moc_qgscoordinatereferencesystemmodel.cpp"
|
||||
#include "qgscoordinatereferencesystemutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsstringutils.h"
|
||||
|
||||
#include <QFont>
|
||||
|
||||
@ -706,7 +707,7 @@ bool QgsCoordinateReferenceSystemProxyModel::filterAcceptsRow( int sourceRow, co
|
||||
if ( !mFilterString.trimmed().isEmpty() )
|
||||
{
|
||||
const QString name = sourceModel()->data( sourceIndex, static_cast<int>( QgsCoordinateReferenceSystemModel::CustomRole::Name ) ).toString();
|
||||
if ( !( name.contains( mFilterString, Qt::CaseInsensitive )
|
||||
if ( !( QgsStringUtils::containsByWord( name, mFilterString )
|
||||
|| authid.contains( mFilterString, Qt::CaseInsensitive ) ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ __author__ = "Nyall Dawson"
|
||||
__date__ = "30/08/2016"
|
||||
__copyright__ = "Copyright 2016, The QGIS Project"
|
||||
|
||||
from qgis.PyQt.QtCore import Qt
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
from qgis.core import (
|
||||
QgsStringReplacement,
|
||||
@ -371,6 +372,84 @@ class PyQgsStringUtils(unittest.TestCase):
|
||||
QgsStringUtils.truncateMiddleOfString("this is a test", 0), "…"
|
||||
)
|
||||
|
||||
def test_contains_by_word(self):
|
||||
"""
|
||||
Test QgsStringUtils.containsByWord
|
||||
"""
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "world hello"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "hello\tworld"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "hello"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "world"))
|
||||
self.assertFalse(QgsStringUtils.containsByWord("Hello World", "goodbye"))
|
||||
|
||||
# Case insensitive (default)
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "WORLD"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("HELLO WORLD", "world"))
|
||||
|
||||
# Case sensitive
|
||||
self.assertFalse(
|
||||
QgsStringUtils.containsByWord(
|
||||
"Hello World", "WORLD", Qt.CaseSensitivity.CaseSensitive
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord(
|
||||
"Hello World", "World", Qt.CaseSensitivity.CaseSensitive
|
||||
)
|
||||
)
|
||||
|
||||
# Test that parts of words can match
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord("Worldmap_Winkel_II", "winkel world")
|
||||
)
|
||||
self.assertTrue(QgsStringUtils.containsByWord("HelloWorld", "hello world"))
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord("SuperCalifragilistic", "super cal fragi")
|
||||
)
|
||||
|
||||
# empty strings
|
||||
self.assertFalse(QgsStringUtils.containsByWord("Hello World", ""))
|
||||
self.assertFalse(QgsStringUtils.containsByWord("Hello World", " "))
|
||||
self.assertFalse(QgsStringUtils.containsByWord("", "hello"))
|
||||
self.assertFalse(QgsStringUtils.containsByWord(" ", "hello"))
|
||||
self.assertFalse(QgsStringUtils.containsByWord("", ""))
|
||||
self.assertFalse(QgsStringUtils.containsByWord(" ", ""))
|
||||
self.assertFalse(QgsStringUtils.containsByWord(" ", " "))
|
||||
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello, World!", "hello world"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello-World", "hello world"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello_World", "hello world"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello\tWorld\n", "hello world"))
|
||||
|
||||
# test multiple words in different orders
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord("The Quick Brown Fox", "fox quick")
|
||||
)
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord("The Quick Brown Fox", "brown the fox")
|
||||
)
|
||||
self.assertFalse(
|
||||
QgsStringUtils.containsByWord("The Quick Brown Fox", "fox quick jumping")
|
||||
)
|
||||
|
||||
# test handling of unicode characters"""
|
||||
self.assertTrue(QgsStringUtils.containsByWord("École Primaire", "école"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("München Stadt", "münchen"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("北京市", "北京"))
|
||||
|
||||
# test handling of various whitespace scenarios
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello World", "hello world"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello\tWorld", "hello world"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("Hello\nWorld", "hello world"))
|
||||
self.assertTrue(
|
||||
QgsStringUtils.containsByWord(" Hello World ", "hello world")
|
||||
)
|
||||
|
||||
# Test handling of word boundaries
|
||||
self.assertTrue(QgsStringUtils.containsByWord("HelloWorld", "hello"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("WorldHello", "hello"))
|
||||
self.assertTrue(QgsStringUtils.containsByWord("TheHelloWorld", "hello world"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user