📄 qregexp.cpp
字号:
parentheses is more efficient than using capturing parentheses since the regexp engine has to do less book-keeping. Both capturing and non-capturing parentheses may be nested. \target assertions \section1 Assertions Assertions make some statement about the text at the point where they occur in the regexp but they do not match any characters. In the following list <b>\e {E}</b> stands for any expression. \table \row \i <b>^</b> \i The caret signifies the beginning of the string. If you wish to match a literal \c{^} you must escape it by writing \c{\\^}. For example, <b>^#include</b> will only match strings which \e begin with the characters '#include'. (When the caret is the first character of a character set it has a special meaning, see \link #sets-of-characters Sets of Characters \endlink.) \row \i <b>$</b> \i The dollar signifies the end of the string. For example <b>\d\s*$</b> will match strings which end with a digit optionally followed by whitespace. If you wish to match a literal \c{$} you must escape it by writing \c{\\$}. \row \i <b>\\b</b> \i A word boundary. For example the regexp <b>\\bOK\\b</b> means match immediately after a word boundary (e.g. start of string or whitespace) the letter 'O' then the letter 'K' immediately before another word boundary (e.g. end of string or whitespace). But note that the assertion does not actually match any whitespace so if we write <b>(\\bOK\\b)</b> and we have a match it will only contain 'OK' even if the string is "Its <u>OK</u> now". \row \i <b>\\B</b> \i A non-word boundary. This assertion is true wherever <b>\\b</b> is false. For example if we searched for <b>\\Bon\\B</b> in "Left on" the match would fail (space and end of string aren't non-word boundaries), but it would match in "t<u>on</u>ne". \row \i <b>(?=\e E)</b> \i Positive lookahead. This assertion is true if the expression matches at this point in the regexp. For example, <b>const(?=\\s+char)</b> matches 'const' whenever it is followed by 'char', as in 'static <u>const</u> char *'. (Compare with <b>const\\s+char</b>, which matches 'static <u>const char</u> *'.) \row \i <b>(?!\e E)</b> \i Negative lookahead. This assertion is true if the expression does not match at this point in the regexp. For example, <b>const(?!\\s+char)</b> matches 'const' \e except when it is followed by 'char'. \endtable \target wildcard-matching \section1 Wildcard Matching (globbing) Most command shells such as \e bash or \e cmd.exe support "file globbing", the ability to identify a group of files by using wildcards. The setWildcard() function is used to switch between regexp and wildcard mode. Wildcard matching is much simpler than full regexps and has only four features: \table \row \i <b>c</b> \i Any character represents itself apart from those mentioned below. Thus <b>c</b> matches the character \e c. \row \i <b>?</b> \i This matches any single character. It is the same as <b>.</b> in full regexps. \row \i <b>*</b> \i This matches zero or more of any characters. It is the same as <b>.*</b> in full regexps. \row \i <b>[...]</b> \i Sets of characters can be represented in square brackets, similar to full regexps. Within the character class, like outside, backslash has no special meaning. \endtable For example if we are in wildcard mode and have strings which contain filenames we could identify HTML files with <b>*.html</b>. This will match zero or more characters followed by a dot followed by 'h', 't', 'm' and 'l'. \target perl-users \section1 Notes for Perl Users Most of the character class abbreviations supported by Perl are supported by QRegExp, see \link #characters-and-abbreviations-for-sets-of-characters characters and abbreviations for sets of characters \endlink. In QRegExp, apart from within character classes, \c{^} always signifies the start of the string, so carets must always be escaped unless used for that purpose. In Perl the meaning of caret varies automagically depending on where it occurs so escaping it is rarely necessary. The same applies to \c{$} which in QRegExp always signifies the end of the string. QRegExp's quantifiers are the same as Perl's greedy quantifiers. Non-greedy matching cannot be applied to individual quantifiers, but can be applied to all the quantifiers in the pattern. For example, to match the Perl regexp <b>ro+?m</b> requires: \code QRegExp rx( "ro+m" ); rx.setMinimal( TRUE ); \endcode The equivalent of Perl's \c{/i} option is setCaseSensitive(FALSE). Perl's \c{/g} option can be emulated using a \link #cap_in_a_loop loop \endlink. In QRegExp <b>.</b> matches any character, therefore all QRegExp regexps have the equivalent of Perl's \c{/s} option. QRegExp does not have an equivalent to Perl's \c{/m} option, but this can be emulated in various ways for example by splitting the input into lines or by looping with a regexp that searches for newlines. Because QRegExp is string oriented there are no \A, \Z or \z assertions. The \G assertion is not supported but can be emulated in a loop. Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp equivalents for $`, $' or $+. Perl's capturing variables, $1, $2, ... correspond to cap(1) or capturedTexts()[1], cap(2) or capturedTexts()[2], etc. To substitute a pattern use QString::replace(). Perl's extended \c{/x} syntax is not supported, nor are directives, e.g. (?i), or regexp comments, e.g. (?#comment). On the other hand, C++'s rules for literal strings can be used to achieve the same: \code QRegExp mark( "\\b" // word boundary "[Mm]ark" // the word we want to match ); \endcode Both zero-width positive and zero-width negative lookahead assertions (?=pattern) and (?!pattern) are supported with the same syntax as Perl. Perl's lookbehind assertions, "independent" subexpressions and conditional expressions are not supported. Non-capturing parentheses are also supported, with the same (?:pattern) syntax. See QStringList::split() and QStringList::join() for equivalents to Perl's split and join functions. Note: because C++ transforms \\'s they must be written \e twice in code, e.g. <b>\\b</b> must be written <b>\\\\b</b>. \target code-examples \section1 Code Examples \code QRegExp rx( "^\\d\\d?$" ); // match integers 0 to 99 rx.search( "123" ); // returns -1 (no match) rx.search( "-6" ); // returns -1 (no match) rx.search( "6" ); // returns 0 (matched as position 0) \endcode The third string matches '<u>6</u>'. This is a simple validation regexp for integers in the range 0 to 99. \code QRegExp rx( "^\\S+$" ); // match strings without whitespace rx.search( "Hello world" ); // returns -1 (no match) rx.search( "This_is-OK" ); // returns 0 (matched at position 0) \endcode The second string matches '<u>This_is-OK</u>'. We've used the character set abbreviation '\S' (non-whitespace) and the anchors to match strings which contain no whitespace. In the following example we match strings containing 'mail' or 'letter' or 'correspondence' but only match whole words i.e. not 'email' \code QRegExp rx( "\\b(mail|letter|correspondence)\\b" ); rx.search( "I sent you an email" ); // returns -1 (no match) rx.search( "Please write the letter" ); // returns 17 \endcode The second string matches "Please write the <u>letter</u>". The word 'letter' is also captured (because of the parentheses). We can see what text we've captured like this: \code QString captured = rx.cap( 1 ); // captured == "letter" \endcode This will capture the text from the first set of capturing parentheses (counting capturing left parentheses from left to right). The parentheses are counted from 1 since cap( 0 ) is the whole matched regexp (equivalent to '&' in most regexp engines). \code QRegExp rx( "&(?!amp;)" ); // match ampersands but not & QString line1 = "This & that"; line1.replace( rx, "&" ); // line1 == "This & that" QString line2 = "His & hers & theirs"; line2.replace( rx, "&" ); // line2 == "His & hers & theirs" \endcode Here we've passed the QRegExp to QString's replace() function to replace the matched text with new text. \code QString str = "One Eric another Eirik, and an Ericsson." " How many Eiriks, Eric?"; QRegExp rx( "\\b(Eric|Eirik)\\b" ); // match Eric or Eirik int pos = 0; // where we are in the string int count = 0; // how many Eric and Eirik's we've counted while ( pos >= 0 ) { pos = rx.search( str, pos ); if ( pos >= 0 ) { pos++; // move along in str count++; // count our Eric or Eirik } } \endcode We've used the search() function to repeatedly match the regexp in the string. Note that instead of moving forward by one character at a time \c pos++ we could have written \c {pos += rx.matchedLength()} to skip over the already matched string. The count will equal 3, matching 'One <u>Eric</u> another <u>Eirik</u>, and an Ericsson. How many Eiriks, <u>Eric</u>?'; it doesn't match 'Ericsson' or 'Eiriks' because they are not bounded by non-word boundaries. One common use of regexps is to split lines of delimited data into their component fields. \code str = "Trolltech AS\twww.trolltech.com\tNorway"; QString company, web, country; rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" ); if ( rx.search( str ) != -1 ) { company = rx.cap( 1 ); web = rx.cap( 2 ); country = rx.cap( 3 ); } \endcode In this example our input lines have the format company name, web address and country. Unfortunately the regexp is rather long and not very versatile -- the code will break if we add any more fields. A simpler and better solution is to look for the separator, '\t' in this case, and take the surrounding text. The QStringList split() function can take a separator string or regexp as an argument and split a string accordingly. \code QStringList field = QStringList::split( "\t", str ); \endcode Here field[0] is the company, field[1] the web address and so on. To imitate the matching of a shell we can use wildcard mode. \code QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything rx.setWildcard( TRUE ); // now it's a valid wildcard regexp rx.exactMatch( "index.html" ); // returns TRUE rx.exactMatch( "default.htm" ); // returns FALSE rx.exactMatch( "readme.txt" ); // returns FALSE \endcode Wildcard matching can be convenient because of its simplicity, but any wildcard regexp can be defined using full regexps, e.g. <b>.*\.html$</b>. Notice that we can't match both \c .html and \c .htm files with a wildcard unless we use <b>*.htm*</b> which will also match 'test.html.bak'. A full regexp gives us the precision we need, <b>.*\\.html?$</b>. QRegExp can match case insensitively using setCaseSensitive(), and can use non-greedy matching, see setMinimal(). By default QRegExp uses full regexps but this can be changed with setWildcard(). Searching can be forward with search() or backward with searchRev(). Captured text can be accessed using capturedTexts() which returns a string list of all captured strings, or using cap() which returns the captured string for the given index. The pos() function takes a match index and returns the position in the string where the match was made (or -1 if there was no match). \sa QRegExpValidator QString QStringList \target member-function-documentation*/const int NumBadChars = 64;#define BadChar( ch ) ( (ch).unicode() % NumBadChars )const int NoOccurrence = INT_MAX;const int EmptyCapture = INT_MAX;const int InftyLen = INT_MAX;const int InftyRep = 1025;const int EOS = -1;static bool isWord( QChar ch ){ return ch.isLetterOrNumber() || ch == QChar( '_' );}/* Merges two QMemArrays of ints and puts the result into the first one.*/static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b ){ int asize = a->size(); int bsize = b.size(); if ( asize == 0 ) { *a = b.copy();#ifndef QT_NO_REGEXP_OPTIM } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) { a->resize( asize + 1 ); (*a)[asize] = b[0];#endif } else if ( bsize >= 1 ) { int csize = asize + bsize; QMemArray<int> c( csize ); int i = 0, j = 0, k = 0; while ( i < asize ) { if ( j < bsize ) { if ( (*a)[i] == b[j] ) { i++; csize--; } else if ( (*a)[i] < b[j] ) { c[k++] = (*a)[i++]; } else { c[k++] = b[j++]; } } else { memcpy( c.data() + k, (*a).data() + i, (asize - i) * sizeof(int) ); break; } } c.resize( csize ); if ( j < bsize ) memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) ); *a = c; }}/* Merges two disjoint QMaps of (int, int) pairs and puts the result into the first one.*/static void mergeInto( QMap<int, int> *a, const QMap<int, int>& b ){ QMap<int, int>::ConstIterator it; for ( it = b.begin(); it != b.end(); ++it ) a->insert( it.key(), *it );}/* Returns the value associated to key k in QMap m of (int, int) pairs, or 0 if no such value is explicitly present.*/static int at( const QMap<int, int>& m, int k ){ QMap<int, int>::ConstIterator it = m.find( k ); if ( it == m.end() ) return 0; else return *it;}#ifndef QT_NO_REGEXP_WILDCARD/* Translates a wildcard pattern to an equivalent regular expression pattern (e.g., *.cpp to .*\.cpp).*/static QString wc2rx( const QString& wc_str ){ int wclen = wc_str.length(); QString rx = QString::fromLatin1( "" ); int i = 0; const QChar *wc = wc_str.unicode(); while ( i < wclen ) { QChar c = wc[i++]; switch ( c.unicode() ) { case '*': rx += QString::fromLatin1( ".*" ); break; case '?': rx += QChar( '.' ); break; case '$': case '(': case ')':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -