Que sont exactement les expressions régulières ? Le site Web PHP chinois suivant vous présentera les expressions régulières. [Lecture recommandée : Tutoriel vidéo sur les expressions régulières]
Lors de l'écriture de programmes ou de pages Web qui traitent des chaînes, il est souvent nécessaire de trouver des chaînes qui correspondent à certaines règles complexes. Les expressions régulières sont des outils utilisés pour décrire ces règles. En d’autres termes, les expressions régulières sont des codes qui enregistrent des règles textuelles.
Il est très probable que vous ayez utilisé le caractère générique (wildcard) utilisé pour la recherche de fichiers sous Windows/Dos, c'est-à-dire * et ?. Si vous souhaitez rechercher tous les documents Word dans un certain répertoire, vous devez rechercher *.doc. Ici, * sera interprété comme une chaîne arbitraire. Semblables aux caractères génériques, les expressions régulières sont également des outils utilisés pour la correspondance de texte, mais elles peuvent décrire vos besoins avec plus de précision que les caractères génériques - bien sûr, au prix d'être plus compliquées - par exemple, vous pouvez écrire une expression régulière, Utilisé pour tout trouver. des chaînes commençant par 0, suivies de 2-3 chiffres, puis d'un trait d'union "-" et enfin de 7 ou 8 chiffres.
Démarrage
La meilleure façon d'apprendre les expressions régulières est de commencer par des exemples. Après avoir compris les exemples, vous pouvez ensuite modifier les exemples et expérimenter. Un certain nombre d'exemples simples sont donnés ci-dessous et sont expliqués en détail.
Supposons que vous recherchiez salut dans un roman anglais, vous pouvez utiliser l'expression régulière salut.
C'est presque l'expression régulière la plus simple. Elle peut correspondre avec précision à une chaîne comme celle-ci : elle se compose de deux caractères, le premier caractère est h et le caractère suivant est i. Habituellement, les outils qui traitent les expressions régulières proposent une option permettant d'ignorer la casse. Si cette option est sélectionnée, elle peut correspondre à l'un des quatre cas hi, HI, Hi et hI.
Malheureusement, de nombreux mots contiennent les deux caractères consécutifs salut, comme lui, histoire, haut, etc. Si vous utilisez hi pour effectuer une recherche, le salut à l'intérieur sera également trouvé. Si nous voulons trouver le mot hi avec précision, nous devons utiliser bhib.
b est un code spécial spécifié par une expression régulière (enfin, certaines personnes l'appellent un métacaractère), qui représente le début ou la fin d'un mot, c'est-à-dire la limite d'un mot. Bien que les mots anglais soient généralement séparés par des espaces, des signes de ponctuation ou des nouvelles lignes, b ne correspond à aucun de ces caractères de séparation de mots, il ne correspond qu'à une seule position.
Si ce que vous recherchez est salut suivi d'une Lucy non loin, vous devriez utiliser bhib.*bLucyb.
Ici, . est un autre métacaractère, correspondant à n'importe quel caractère sauf les nouvelles lignes. * est également un métacaractère, mais il ne représente pas un caractère, ni une position, mais une quantité - il spécifie que le contenu avant * peut être utilisé de manière répétée un nombre illimité de fois pour faire correspondre l'expression entière. Par conséquent, .* ensemble signifie n’importe quel nombre de caractères n’incluant pas de nouvelle ligne. Maintenant, la signification de bhib.*bLucyb est évidente : d'abord le mot salut, puis un nombre quelconque de caractères (mais pas de nouvelles lignes), et enfin le mot Lucy.
Si d'autres métacaractères sont utilisés ensemble, nous pouvons construire des expressions régulières plus puissantes. Par exemple, l'exemple suivant :
0dd-dddddddd correspond à une chaîne qui commence par 0, puis deux chiffres, puis un trait d'union "-", et enfin 8 chiffres (c'est-à-dire des numéros de téléphone chinois. Bien sûr , cet exemple ne peut faire correspondre que l'indicatif régional à 3 chiffres).
Le d ici est un nouveau métacaractère, correspondant à un seul chiffre (0, ou 1, ou 2, ou...). - n'est pas un métacaractère, il correspond seulement à lui-même - le trait d'union (ou le signe moins, ou le tiret, ou peu importe comment vous voulez l'appeler).
Afin d'éviter tant de répétitions gênantes, on peut aussi écrire cette expression comme ceci : 0d{2}-d{8}. Le {2} ({8}) après d signifie ici que le d précédent doit être répété et mis en correspondance 2 fois (8 fois) de suite.
Test des expressions régulières
Si vous ne trouvez pas les expressions régulières difficiles à lire et à écrire, soit vous êtes un génie, soit vous n'êtes pas de la Terre. La syntaxe des expressions régulières peut prêter à confusion, même pour les personnes qui l'utilisent régulièrement. Parce qu’elles sont difficiles à lire et à écrire et sujettes aux erreurs, il est nécessaire de trouver un outil pour tester les expressions régulières.
Certains détails des expressions régulières sont différents selon les environnements. Ce tutoriel présente le comportement des expressions régulières sous Microsoft .Net Framework 4.5. Par conséquent, je vous recommande la version .Net que j'ai écrite. Veuillez vous référer aux instructions sur cette page pour installer et exécuter le logiciel.
Ce qui suit est une capture d'écran de Regester en cours d'exécution :
Métacaractères
Maintenant, vous connaissez déjà quelques métacaractères utiles, tels que b, .,* et d. Il y a plus de métacaractères dans les expressions régulières. Par exemple, s correspond à n'importe quel caractère d'espacement, y compris les espaces, les tabulations, les nouvelles lignes, les espaces chinois pleine largeur, etc. w correspond à des lettres, des chiffres, des traits de soulignement ou des caractères chinois, etc.
Voici quelques exemples supplémentaires :
baw*b correspond aux mots commençant par la lettre a - d'abord le début d'un mot (b), puis la lettre a, puis n'importe quel nombre de lettres ou chiffres (w*), suivis de la fin du mot (b).
d+ correspond à 1 ou plusieurs nombres consécutifs. Le + ici est un métacaractère similaire à *, la différence est que * correspond à un nombre répété de fois (éventuellement 0 fois), tandis que + correspond à une répétition 1 ou plusieurs fois.
bw{6}b correspond à des mots d'exactement 6 caractères.
Les métacaractères ^ (le symbole sur la même position clé que le chiffre 6) et $ correspondent tous deux à une position, ce qui est quelque peu similaire à b. ^ correspond au début de la chaîne que vous recherchez et $ correspond à la fin. Ces deux codes sont très utiles lors de la vérification du contenu saisi. Par exemple, si un site Web exige que le numéro QQ que vous remplissez soit composé de 5 à 12 chiffres, vous pouvez utiliser : ^d{5,12}$.
Le {5,12} ici est similaire au {2} introduit précédemment, sauf que le match {2} ne peut être répété que deux fois, ni plus, ni moins, et {5,12} est répété . Le nombre de fois ne peut pas être inférieur à 5 fois et ne peut pas être supérieur à 12 fois, sinon ils ne correspondront pas.
Parce que ^ et $ sont utilisés, la chaîne d'entrée entière doit être utilisée pour correspondre à d{5,12}, ce qui signifie que l'entrée entière doit être composée de 5 à 12 nombres, donc si l'entrée Si le numéro QQ peut correspondre à cette expression régulière, il répond aux exigences.
Semblable à l'option permettant d'ignorer la casse, certains outils de traitement d'expressions régulières ont également la possibilité de traiter plusieurs lignes. Si cette option est sélectionnée, la signification de ^ et $ devient le début et la fin de la ligne correspondante.
Échappement du caractère
Si vous souhaitez rechercher le métacaractère lui-même, par exemple si vous recherchez ., ou *, il y a un problème : vous ne pouvez pas les spécifier car ils seront interprétés comme autre chose. A ce moment, vous devez utiliser pour annuler la signification particulière de ces caractères. Par conséquent, vous devez utiliser . Bien sûr, pour rechercher lui-même, vous devez également utiliser \.
Par exemple : deerchao.net correspond à deerchao.net, C:\Windows correspond à C:Windows.
Répéter
Vous avez déjà vu les manières précédentes de faire correspondre et de répéter *, +, {2}, {5,12}. Voici tous les qualificatifs des expressions régulières (codes qui spécifient un nombre, tels que *, {5,12}, etc.) :
Voici quelques exemples d'utilisation répétition :
Windowsd+ correspond à Windows suivi d'un ou plusieurs chiffres
^w+ correspond au premier mot d'une ligne (ou au premier mot de la chaîne entière, la signification spécifique de la correspondance dépend de la option Paramètres)
Classe de caractères
Pour trouver des chiffres, des lettres ou des chiffres, les espaces sont très simples, car il existe déjà des métacaractères correspondant à ces jeux de caractères, mais si vous voulez faire correspondre il n'y a pas prédéfini Que faut-il faire pour définir un jeu de caractères de métacaractères (tels que les voyelles a, e, i, o, u) ?
C'est très simple, il vous suffit de les lister entre crochets, comme [aeiou] correspond à n'importe quelle voyelle anglaise, [.?!] correspond aux signes de ponctuation (. ou ? ou !) .
Nous pouvons également facilement spécifier une plage de caractères. Par exemple, [0-9] représente exactement la même signification que d : de la même manière, [a-z0-9A-Z_] est également complètement équivalent. en w (si seul l'anglais est considéré).
Faisons une analyse dessus : il y a d'abord un caractère d'échappement (, il peut apparaître 0 ou 1 fois (?), puis il y a un 0, suivi de 2 chiffres (d{2}) , puis un de ) ou - ou un espace, qui apparaît 1 fois ou non (?), et enfin 8 chiffres (d{8}).
Condition de branchement
Malheureusement, l'expression peut également correspondre à des formats "incorrects" tels que 010)12345678 ou (022-87654321). Pour résoudre ce problème, nous devons définir les conditions de branchement. Les conditions de branchement dans les expressions régulières font référence à plusieurs règles. Si l'une des règles est remplie, elle doit être considérée comme une correspondance. La méthode spécifique consiste à séparer les différentes règles avec | Peu importe, regardez l'exemple :
0d{2}-d{8}|0d{3}-d{7} Cette expression peut correspondre à deux numéros de téléphone séparés par des tirets : l'un est un indicatif régional à trois chiffres. , numéro local à 8 chiffres (tel que 010-12345678), l'un est un indicatif régional à 4 chiffres, un numéro local à 7 chiffres (0376-2233445)
(0d{2})[- ]?d{ 8 }|0d{2}[- ]?d{8} Cette expression correspond à un numéro de téléphone avec un indicatif régional à 3 chiffres. L'indicatif régional peut être mis entre parenthèses ou non. L'indicatif régional et le numéro local peuvent être séparés. par un trait d'union ou un espace. , ou il n'y a pas d'intervalle. Vous pouvez essayer d'utiliser des conditions de branche pour développer cette expression afin de prendre également en charge les indicatifs régionaux à 4 chiffres. 4}|d{5}. Pour faire correspondre les codes postaux aux États-Unis. La règle pour les codes postaux aux États-Unis est de 5 chiffres, ou 9 chiffres séparés par des tirets. La raison pour laquelle cet exemple est donné est qu'il illustre un problème. : lorsque vous utilisez des conditions de branche, faites attention à chacune. L'ordre des conditions si vous le modifiez en d{5}|d{5}-d{4}, alors uniquement le code postal à 5 chiffres (et les 5 premiers). chiffres du code postal à 9 chiffres) seront mis en correspondance. Lors des conditions de branchement, chaque condition sera testée de gauche à droite. Si une certaine branche est satisfaite, les autres conditions ne seront pas prises en compte. >
nous. Nous avons déjà mentionné comment répéter un seul caractère (ajoutez simplement le qualificatif après le caractère), mais que se passe-t-il si vous souhaitez répéter plusieurs caractères ? Vous pouvez utiliser des parenthèses pour spécifier des sous-expressions (également appelées regroupement) ; alors Vous pouvez spécifier le nombre de répétitions de cette sous-expression, et vous pouvez également effectuer d'autres opérations sur la sous-expression (sera présenté plus tard).(d{1,3}.){3}d{1,3} est une simple expression de correspondance d'adresse IP. Pour comprendre cette expression, analysez-la dans l'ordre suivant : d{1,3} correspond à un nombre de 1 à 3 chiffres, (d{1,3}.){3} correspond à un nombre à trois chiffres plus un point (ce Le tout est ce groupe) répété trois fois, et enfin un nombre à trois chiffres (d{1,3}) est ajouté.
Malheureusement, elle correspondra également à l'impossible adresse IP 256.300.888.999. Si vous pouvez utiliser la comparaison arithmétique, vous pourrez peut-être résoudre ce problème simplement, mais les expressions régulières ne fournissent aucune fonction mathématique, vous ne pouvez donc utiliser que de longues classes de regroupement, de sélection et de caractères pour décrire une adresse IP correcte :( (2 [0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd? ).
La clé pour comprendre cette expression est de comprendre 2[0-4]d|25[0-5]|[01]?dd?. Je n'entrerai pas dans les détails ici. Vous devriez pouvoir le faire. pour l'analyser vous-même.
Antonymes
Parfois, il est nécessaire de trouver des caractères qui n'appartiennent pas à une classe de caractères facilement définie. Par exemple, si vous souhaitez rechercher un caractère autre que des chiffres, vous devez utiliser l'antonyme :
Exemple : S+ correspond à une chaîne qui ne contient pas de caractères d'espacement.
]+> correspond à une chaîne commençant par un entre crochets.
Référence arrière
Après avoir utilisé des parenthèses pour spécifier une sous-expression, le texte correspondant à cette sous-expression (c'est-à-dire le contenu capturé par ce groupe) peut être utilisé dans des expressions ou d'autres programmes. Par défaut, chaque groupe aura automatiquement un numéro de groupe. La règle est la suivante : de gauche à droite, avec le crochet gauche du groupe comme marque, le numéro de groupe du premier groupe apparaissant est 1, le deuxième est 2 et ainsi de suite.
La référence arrière est utilisée pour rechercher à plusieurs reprises le texte correspondant à un groupe précédent. Par exemple, 1 représente le texte correspondant au groupe 1. Difficile à comprendre ? Veuillez consulter l'exemple :
b(w+)bs+1b peut être utilisé pour faire correspondre des mots répétés, comme go go ou kitty kitty. Cette expression est d'abord un mot, c'est-à-dire plus d'une lettre ou un chiffre (b(w+)b) entre le début et la fin du mot. Ce mot sera capturé dans le groupe numéroté 1, puis 1. Un ou plusieurs espaces. caractères (s+), et enfin le contenu capturé dans le groupe 1 (c'est-à-dire le mot précédemment correspondant) (1).
Vous pouvez également spécifier vous-même le nom de groupe de la sous-expression. Pour spécifier le nom de groupe d'une sous-expression, utilisez la syntaxe suivante : (?
Lors de l'utilisation de parenthèses, il existe de nombreuses syntaxes spéciales. Voici quelques-unes des plus couramment utilisées :
Assertions de largeur nulle
Les quatre suivantes sont utilisées pour rechercher du contenu qui n'est pas inclus dans ces contenu) avant ou après, c'est-à-dire qu'ils sont utilisés comme b, ^, $ pour spécifier une position qui doit remplir certaines conditions (c'est-à-dire des assertions), ils sont donc également appelés assertions de largeur nulle. Il est préférable d'utiliser un exemple pour illustrer :
(?=exp) est également appelée assertion anticipée de prédiction positive de largeur nulle. Elle affirme que l'expression exp peut être mise en correspondance après la position où elle apparaît. Par exemple, bw+(?=ingb) correspond à la partie avant d'un mot se terminant par ing (autre que ing). Par exemple, lorsque vous recherchez Je chante pendant que vous dansez., cela correspondra à chanter et à danser.
(?
Si vous souhaitez ajouter une virgule entre tous les trois chiffres dans un nombre très long (ajouté depuis la droite, bien sûr), vous pouvez trouver la partie où vous devez ajouter des virgules devant et à l'intérieur comme ceci : ((( ?
L'exemple suivant utilise les deux assertions : (?
Assertion négative de largeur nulle
Nous avons mentionné plus tôt comment trouver des caractères qui ne sont pas un certain caractère ou qui ne appartiennent pas à une certaine classe de caractères (antonyme). Mais que se passe-t-il si nous voulons simplement nous assurer qu'un certain caractère n'apparaît pas, mais que nous ne voulons pas lui correspondre ? Par exemple, si nous voulons trouver un mot dans lequel la lettre q apparaît, mais que le q n'est pas suivi de la lettre u, nous pouvons essayer ceci :
\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b。
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?
一个更复杂的例子:(?).*(?=)匹配不包含属性的简单HTML标签内里的内容。(?)指定了这样的前缀:被尖括号括起来的单词(比如可能是),然后是.*(任意的字符串),最后是一个后缀(?=)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是的话,后缀就是了。整个表达式匹配的是和之间的内容(再次提醒,不包括前缀和后缀本身)。
注释
小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以前面的一个表达式写成这样:
(?<= # 断言要匹配的文本的前缀 <(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签) ) # 前缀结束 .* # 匹配任意文本 (?= # 断言要匹配的文本的后缀 <\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签 ) # 后缀结束
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
处理选项
上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项:
一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。
平衡组/递归匹配
有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用\(.+\)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?
为了避免(和\(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx
这里需要用到以下的语法构造:
(?'group') 把捕获的内容命名为group,并压入堆栈(Stack)
(?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
(?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
(?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。
< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号的内容 ( ( (?'Open'<) #碰到了左括号,在黑板上写一个"Open" [^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?'-Open'>) #碰到了右括号,擦掉一个"Open" [^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败 > #最外层的右括号
平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的
上边已经描述了构造正则表达式的大量元素,但是还有很多没有提到的东西。下面是一些未提到的元素的列表,包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到.net下正则表达式详细的文档。
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!