This time I will bring you regular expressionhow to match a patternstring, what are the notesfor regular expression pattern matching string, as follows This is a practical case, let’s take a look at it.
Introduction
In actual projects, there is a function that needs to parse some strings in specific patterns. In the existing code base, some of the functions that have been implemented are used to detect specific characters. The disadvantage of using this method is:
It is easy to make logical errors
It is easy to miss checking some boundary conditions
The code is complex and difficult to understand and maintain
Poor performance
I saw a cpp in the code base. The entire cpp has more than 2,000 lines of code. There is a method that only parses strings and has more than 400 lines! Comparing the characters one by one, it is really unsightly. Moreover, many of the comments above are expired, and the writing styles of many codes are also different. It can be basically judged that it has been written by many people.
In this case, there is basically no way to continue along this old path, so naturally I thought of using regular expressions. I have no practical application experience in regular expressions, especially about writing matching rules. The first thing I thought of was to find some information on the Internet to get a general understanding. But the result of Du Niang is still very disappointing. (Of course, if you want to search for some more professional knowledge, Du Niang's results will be heartbreaking every time, and they are all the same copies. But usually Du Niang's life is still OK) Later, I gave up on Du Niang's query results. , FQ went outside to look for it, and found some relatively basic videos (requires FQ).
This article can be said to be a summary, introducing the basic knowledge of writing regular expressions to match strings. It is mainly divided into the following two parts:
Basic rules for matching strings
Regular matching, search and replacement
The regular expression rules introduced in this article are ECMAScript. The programming language used is C++. No other aspects will be introduced.
Basic rules for matching strings
1. Match fixed strings
regex e(" abc");
2. Match fixed strings, case-insensitive
regex e("abc", regex_constants::icase);
3. Match one more character than the fixed string, case-insensitive
regex e("abc.", regex_constants::icase); // . Any character except newline. 1 character
4. Match 0 or 1 character
regex e("abc?"); // ? Zero or 1 preceding character. Match?The previous character
5. Match 0 or more characters
regex e("abc*"); // * Zero or more preceding character. Match *previous character
6. Match 1 or more characters
regex e("abc+"); // + One or more preceding character. Match +Previous character
7. Match characters in a specific string
regex e("ab[cd]*"); // [...] Any character inside square brackets. Matches any character within []
8. Matches characters in non-specific strings
regex e("ab[^cd]* "); // [...] Any character not inside square brackets. Matches any character not inside []
9. Matches a specific string, and the specified number
regex e("ab[cd]{3}"); // {n} matches any character before {}, and the number of characters is 3
10. 匹配特定字符串,指定数量范围
regex e("ab[cd]{3,}"); // {n} 匹配{}之前任意字符,且字符个数为3个或3个以上 regex e("ab[cd]{3,5}"); // {n} 匹配{}之前任意字符,且字符个数为3个以上,5个以下闭区间
11. 匹配规则中的某一个规则
regex e("abc|de[fg]"); // | 匹配|两边的任意一个规则
12. 匹配分组
regex e("(abc)de+"); // () ()表示一个子分组
13. 匹配子分组
regex e("(abc)de+\\1"); // () ()表示一个子分组,而\1表示在此位置匹配第一个分组的内容 regex e("(abc)c(de+)\\2\\1"); // \2 表示的是在此匹配第二个分组的内容
14. 匹配某个字符串开头
regex e("^abc."); // ^ begin of the string 查找以abc开头的子字符串
15. 匹配某个字符串结尾
regex e("abc.$"); // $ end of the string 查找以abc结尾的子字符串
以上是最基本的匹配模式的书写。通常如果要匹配特定的字符,需要使用\进行转义,比如在匹配字符串中需要匹配".",那么在匹配字符串中应该在特定字符前加上\。出了以上的基本规则,如果还不满足特定的需要,那么可以参考此链接。使用了解基本的匹配模式后,需要使用正则表达式进行匹配、查找或者替代。
正则匹配、查找与替代
书写好模式字符串后,需要将待匹配的字符串和模式字符串进行一定规则的匹配。包括三种方式:匹配(regex_match)、查找(regex_search)、替换(regex_replace)。
匹配很简单,直接将待匹配字符串和模式字符串传入到regex_match中,返回一个bool量来指明待匹配的字符串是否满足模式字符串的规则。匹配整个str字符串。
bool match = regex_match(str, e); // 匹配整个字符串str
查找是在整个字符串中找到和满足模式字符串的子字符串。也就是只要str中存在满足模式字符串就会返回true。
bool match = regex_search(str, e); // 查找字符串str中匹配e规则的子字符串
但是很多情况下,光是返回一个是否匹配的bool量是不够的,我们需要拿到匹配的子字符串。那么就需要在模式字符串中将匹配字符串分组,参考【匹配字符串的基本规则】第12点。再将smatch传入到regex_search中,就可以获得满足每个子分组的字符串。
smatch m; bool found = regex_search(str, m, e); for (int n = 0; n < m.size(); ++n) { cout << "m[" << n << "].str()=" << m[n].str() << endl; }
替换也是基于模式字符串在分组情况下完成的。
cout << regex_replace(str, e, "$1 is on $2");
此时,会在满足分组1和分组2的字符串中间加上“ is on”。
以上三个函数有很多版本的重载,可以满足不同情况下的需求。
实战
要求:找出满足sectionA("sectionB")或者sectionA ("sectionB")的模式字符串。且分离出sectionA、sectionB。sectionA和sectionB不会出现数字,字符可大小写,至少有一个字符。
分析:根据要求,大致可分为两个部分,也就是sectionA和sectionaB。这是就需要用到分组。
第一步:写出满足section情况的模式字符串
[a-zA-Z]+
第二步:在sectionA和sectionB中可能会出现空格。暂且假设至多有1个空格
\\s?
将以上两个情况组合起来,也就是能满足我们需求的模式字符串。但是如何组织才能让其分为两组呢?
[a-zA-Z]+\\s[a-zA-Z]+
上面这种写法肯定不对的,根据分组规则,需要将分组以()进行区分
regex e("([a-zA-Z]+)\\s?\\(\"([a-zA-Z]+)\"\\)");
此时,在\\s?后面的\\(\"是为了满足sectionB外层的引号和括号进行的转义。
以上完成后,可先用regex_match进行匹配,如果匹配,那么继续使用regex_search对字符串进行查找
if (regex_match(str, e)) { smatch m; auto found = regex_search(str, m, e); for (int n = 0; n < m.size(); ++n) { cout << "m[" << n << "].str()=" << m[n].str() << endl; } } else { cout << "Not matched" << endl; }
对象m数组的第一个字符串是满足需求的整个子串,接下来才是满足分组1、分组2的子串。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Detailed explanation of the use of \D metacharacters (equivalent to "[^0-9]") in regular expressions
Regular metacharacters and ordinary character
The above is the detailed content of How to match string with regular expression pattern. For more information, please follow other related articles on the PHP Chinese website!