javascript - Quelle est la différence entre ?= et ?: dans une expression régulière?
天蓬老师
天蓬老师 2017-06-15 09:22:42
0
5
1059

Prenez simplement l'exemple : ajoutez des virgules entre tous les trois nombres

"123456789".replace(/(\d{3})(?:[^$])/g, ",");
//"123,567,9"

"123456789".replace(/(\d{3})(?=[^$])/g, ",");
//"123,456,789"

Un autre exemple apparu dans le forum précédent consiste à ajouter des virgules entre tous les trois nombres

先看看 (?=pattern) 的使用,下面这个是正确的:

function groupByCommas(n) {
  return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(groupByCommas(1234567));    //1,234,567

如果我们把 ?= 换成 ?: 的话:

function groupByCommas(n) {
  return n.toString().replace(/\B(?:(\d{3})+(?!\d))/g, ",");
}
console.log(groupByCommas(1234567));    //1,

Inutile de dire les concepts des deux, j'ai trouvé une réponse disant : La différence est que ?= est une assertion positive positive, et la correspondance n'occupe pas la longueur de la requête tandis que ? : est une correspondance de non-acquisition, et ; la correspondance occupe la longueur de la requête.

Mais je ne comprends toujours pas bien l'affirmation selon laquelle la requête occupe la longueur ici. Expliquez-la à l'exemple. Cela signifie-t-il que le premier exemple (?=[^$]) correspond à une longueur minimale, donc la longueur minimale de. la fin après 123 contient 1 caractère, donc 4 a été remplacé ensemble ? Alors pourquoi ne pas simplement le remplacer directement jusqu’au bout ? Le deuxième exemple (?=(d{3})+(?!d)) correspond à 3 ou à un multiple de 3, et correspond directement à la fin, donc 234567 est également directement remplacé ? Donc ma compréhension est définitivement fausse

Je ne comprends pas très bien. Je vous invite à répondre à ma confusion avec des exemples. Merci beaucoup !

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

répondre à tous(5)
刘奇
  1. "123456789".replace(/(d{3})(?:[^$])/g, ",");
    ()表示捕获型括号,(?:)表示非捕获型括号,所以第一个括号匹配的内容会放在中,第二个括号匹配的内容不会放在中。d{3}表示连续三个数字,[^$]表示匹配一个字符,只要这个字符不是$符号,需要注意的是[]表示匹配里面的任意一个字符,但是肯定是要有一个的,所以[]匹配出来的字符的长度肯定是1,不存在0的情况,另外在[$]里面的$符号是没有特殊含义的,就是$这个字符,而不是匹配字符串的结尾。
    因为d{3}匹配三个字符,[^$]匹配一个字符,所以这个正则匹配4个字符;来看匹配过程,首先"1234"是满足的,"123"匹配d{3},"4"匹配[^$],此时="123",所以"1234"被替换成"123,"。然后从5开始下次匹配,类似的"5678"满足条件,="567", donc "5678" est remplacé par "567". Ensuite, la correspondance commence à partir de 9. Il n'y a pas de correspondance ci-dessous. La correspondance se termine et le résultat est « 123 567,9 ».

  2. "1234567".replace(/B(?:(d{3})+(?!d))/g, ",");
    B匹配非单词边界,也是一个位置,没有宽度,(d{3})+匹配3的倍数数字序列,且个数至少是3个,+是量词,表示1到多次,默认是贪婪的,贪婪就是尽可能多的匹配,(?!d)表示这个位置后面不是数字。
    看例子,首先B不匹配行首,所以匹配的位置移动到"1"后面的位置,此时B匹配1后面的位置,然后"234", "567"匹配d{3},因为是贪婪匹配,所以(d{3})+匹配"234567",然后因为7后面是字符串的结尾了,所以满足断言(?!d)不是数字,所以整个正则的匹配结果是"234567",所以"234567"被替换成了",". 1 ne bouge pas, donc "1234567" devient "1".

  3. "123456789".replace(/(d{3})(?=[^$])/g, ",");
    Cette expression régulière ne répond pas à l'exigence "d'ajouter des virgules à la millième place". "123456789" n'est qu'un cas particulier (le nombre de chiffres est exactement un multiple de 3). le résultat est "123 456,78".

typecho

Occupé ou "consommé" signifie si la partie correspondante peut être mise en correspondance par d'autres expressions régulières (assertions ultérieures, ou la prochaine fois de / /g). S'il est « consommé », il ne peut plus être égalé.

"123456789".replace(/(\d{3})(?=[^$])/g, (m, ) => `{matched=${m} =${}}`);
// => '{matched=123 =123}{matched=456 =456}789'
// (?=) 第一次没有消耗掉4, 第二次会从456..开始

"123456789".replace(/(\d{3})(?:[^$])/g, (m, ) => `{matched=${m} =${}}`);
// => '{matched=1234 =123}{matched=5678 =567}9'
// (?:) 第一次消耗掉4,第二次会从567..开始

De plus, les caractères de l'exemple 1 [^$]是匹配一个非$ n'ont rien à voir avec la fin de la ligne.

巴扎黑

(?=456)匹配一个位置,这个位置后面跟了456
比如123(?=456)会匹配123456中的123,而不会匹配123457中的123,不占用的意思是,至匹配123后面的456并不会被占用掉。
123456 匹配的是123456 , 而123(?=456)456 同样匹配123456 后面加了(?=456) En fait, cela n'a aucun sens.

Vous pouvez utiliser des parenthèses pour modifier la priorité, etc. dans les expressions régulières. De plus, pour la partie entre parenthèses, un numéro sera attribué progressivement de gauche à droite. Vous pourrez utiliser le numéro pour référencer le texte correspondant à cette partie ultérieurement. Dans JS replace里,替换的部分可以用之类的引用这一部分的匹配。
比如(a)1会匹配两个连续的a,([A-Z])1匹配两个连续相同的大小字母,(A-Z)1([a-z])2correspond à deux lettres majuscules et minuscules consécutives, suivies de deux lettres minuscules consécutives (les lettres majuscules et minuscules peuvent être différentes).

Parfois, nous voulons simplement changer la priorité et ne voulons pas attribuer de numéro (rarement utilisé), utilisez simplement (?:)
比如(a)(?:b)(c)12 匹配abcac,但是(a)(b)(c)12匹配abcab.

http://zonxin.github.io/post/...

世界只因有你

Utilisez ()括住的是可以使用(到) pour faire correspondre

Comme indiqué ci-dessous, vous pouvez utiliser 1 $ pour faire correspondre (capturer) la valeur correspondante entre parenthèses,.

a = '123,456';
a.match(/\d{3}(,)/)

Utilisez (?:)则是不捕获这一个。就是不能通过 pour obtenir la valeur obtenue par les parenthèses

a.match(/\d{3}(?:,)/)

Les deux valeurs de correspondance ci-dessus contenant ,的值
来看下面这个,(?=)是用于匹配,但是不出现在结果里的。下面这个的结果就没有,
Regardez la suivante, (?=) est utilisé pour la correspondance, mais n'apparaît pas dans le résultat. Il n'y a aucun résultat pour le suivant

a.match(/\d{3}(?=,)/)
Les résultats des trois codes sont tels qu'indiqués sur la figure

Cette façon d'écrire est très utile. Il y a certains contenus que vous ne souhaitez pas voir apparaître dans les résultats, mais si vous ne l'utilisez pas et que la correspondance est incomplète, vous pouvez l'utiliser 🎜
世界只因有你

Ces deux fonctions sont totalement indépendantes
Mode 1pattern1(?=pattern2)正向肯定断言;模式2(?:pattern3)Regroupement sans capture

1.Modèle 1 : le modèle2 lui-même ne participe pas à la correspondance. Il affirme le résultat de correspondance (ret1) du modèle1 : le contenu après ret1模式1: pattern2 本身不参与匹配,对pattern1的匹配结果(ret1)进行断言:字符串中 ret1之后的内容是否匹配pattern2?若是,则ret1为模式1匹配结果,若否,则ret1不是模式1匹配结果。当然,不匹配pattern1,则也不匹配模式1 dans la chaîne correspond-il au modèle2 ? Si oui, alors ret1 est le résultat de correspondance Modèle 1. Sinon, alors ret1 n'est pas le résultat de correspondance Modèle 1. Bien sûr, si pattern1 ne correspond pas, Pattern1 ne correspondra pas non plus.

Exemple :

  var str1='abc',str2='acb';var reg=/a(?=b)/
  console.log(reg.test(str1),reg.test(str2)) //=>true false
  //因为reg.test(str1)为真,输出匹配结果
  console.log(str1.match(reg)[0])  //=>a

2.Mode 2 est principalement utilisé pour distinguer les 模式2 主要用于区别捕获性分组(pattern4),记为模式3groupes de capture

(pattern4), enregistrés sous la forme

模式3
En mathématiques, les parenthèses sont utilisées pour effectuer une opération prioritaire ; et

, en plus d'isoler le code, pattern4 participe au matching

et stocke les résultats de matching de pattern4模式2(?:pattern3)的非捕获性分组,则表示不会对pattern3的结果进行存储,但本身
pattern3参与了匹配,主要用于对代码进行隔离。也就是要表现()本来的意义,而()在正则
表达式中有了捕获性分组的定义,于是增加一个?:以示区别。这和转义符

Pour le regroupement non capturant du Pattern 2 (?:pattern3), cela signifie que le résultat du motif3 ne sera pas stocké, mais le motif3 lui-même

participe au matching et sert principalement à isoler le code. C'est pour exprimer la signification originale de (), et () a la définition de capturer le regroupement dans l'expression régulière, donc un ?: pour montrer la différence. Cela présente le même avantage que le caractère d'échappement .

Exemple

var  str='abc'
var  reg1=/(\w)(\w)(\w)/
var  reg2=/(\w)(?:\w)(\w)/
//捕获了3次,RegExp.,RegExp.,RegExp....依次存储捕获结果
var ret1=str.match(reg1)
console.log(RegExp.,RegExp.,RegExp.)//=>a b c
var ret2=str.match(reg2)
//捕获了2次
console.log(RegExp.,RegExp.) //=>a c
🎜@luckness a donné une réponse détaillée au contenu de la question, et j'ai répondu au titre de la question. 🎜
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!