Maison  >  Article  >  interface Web  >  Comment faire correspondre une chaîne avec un modèle d'expression régulière

Comment faire correspondre une chaîne avec un modèle d'expression régulière

php中世界最好的语言
php中世界最好的语言original
2018-03-29 11:00:193909parcourir

Cette fois, je vais vous montrer comment faire correspondre le modèle expression régulière à une chaîne, et quelles sont les précautions pour la correspondance de modèle d'expression régulière de chaînes , comme suit C'est un cas pratique, jetons-y un coup d'œil.

Introduction

Dans les projets réels, il existe une fonction qui nécessite d'analyser certaines chaînes dans des modèles spécifiques. Dans la base de code existante, certaines des fonctions qui ont été implémentées sont utilisées pour détecter des caractères spécifiques. Les inconvénients de l'utilisation de cette méthode sont :

  • Logiquement, il est facile de faire des erreurs

  • Il est facile de manquer la vérification de certaines conditions aux limites

  • Le code est complexe et difficile à comprendre et à maintenir

  • Mauvaises performances

J'ai vu qu'il y avait un cpp dans la base de code. L'ensemble du cpp contient plus de 2 000 lignes de code. plus de 400 lignes ! Comparer les personnages un à un, c'est vraiment inesthétique. De plus, bon nombre des commentaires ci-dessus sont obsolètes et les styles d'écriture de nombreux codes sont également différents. On peut fondamentalement juger qu'ils ont été écrits par de nombreuses personnes.

Dans ce cas, il n'y a fondamentalement aucun moyen de continuer sur cette ancienne voie, il est donc naturel de penser à utiliser des expressions régulières. Je n'ai aucune expérience pratique des applications dans les expressions régulières, en particulier en ce qui concerne l'écriture de règles de correspondance. La première chose à laquelle j'ai pensé a été de trouver des informations sur Internet pour avoir une compréhension générale. Mais le résultat de Du Niang reste très décevant. (Bien sûr, si vous souhaitez rechercher des connaissances plus professionnelles, les résultats de Du Niang seront déchirants à chaque fois, et ce sont tous les mêmes copies. Mais généralement, la vie de Du Niang est toujours OK) Plus tard, j'ai abandonné la requête de Du Niang résultats, FQ est sorti pour chercher et a trouvé des

vidéos relativement basiques (nécessite FQ).

Cet article peut être considéré comme un résumé, présentant les connaissances de base de l'écriture d'expressions régulières pour faire correspondre des chaînes. Il est principalement divisé en deux parties suivantes :

  1. Règles de base pour les chaînes de correspondance

  2. Correspondance, recherche et remplacement réguliers

Les règles d'expression régulière présentées dans cet article sont ECMAScript. Le

langage de programmation utilisé est le C++. Aucun autre aspect ne sera introduit.

Règles de base pour faire correspondre les chaînes

1. Faire correspondre les chaînes fixes

regex e("abc");

2. . Correspond à une chaîne fixe, insensible à la casse

regex e("abc", regex_constants::icase);

3. Correspond à un caractère supplémentaire en dehors de la chaîne fixe, insensible à la casse

regex e("abc.", regex_constants::icase);  // .  Any character except newline. 1个字符.

4. Correspond à 0 ou 1 caractères

regex e("abc?");    // ?  Zero or 1 preceding character. 匹配?前一个字符

5. Correspond à 0 ou plusieurs caractères

regex e("abc*");    // *  Zero or more preceding character. 匹配*前一个字符

6. 1 ou plusieurs caractères

regex e("abc+");    // +  One or more preceding character. 匹配+前一个字符

7. Faire correspondre les caractères d'une chaîne spécifique

regex e("ab[cd]*");    // [...] Any character inside square brackets. 匹配[]内的任意字符

8. -chaîne spécifique

regex e("ab[^cd]*");    // [...] Any character not inside square brackets. 匹配非[]内的任意字符

9. Faites correspondre une chaîne spécifique avec le numéro spécifié

regex e("ab[cd]{3}");    // {n}  匹配{}之前任意字符,且字符个数为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中文网其它相关文章!

推荐阅读:

Les métacaractères D (équivalents à "[^0-9]") des expressions régulières sont utilisés en détail

Métacaractères réguliers et caractères ordinaires

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn