Remplacer une Regex groupe de capture avec des majuscules en Javascript
Je voudrais savoir comment faire pour remplacer un groupe de capture avec ses majuscules dans le code JavaScript. Voici une version simplifiée de ce que j'ai essayé jusqu'à présent qui ne fonctionne pas:
> a="foobar"
'foobar'
> a.replace( /(f)/, "$1".toUpperCase() )
'foobar'
> a.replace( /(f)/, String.prototype.toUpperCase.apply("$1") )
'foobar'
Voulez-vous expliquer quel est le problème avec ce code?
- ne pas supprimer un composant d'une question. Je veux savoir pourquoi mon code est la faute de trop.
- Evan, je pensais que j'étais en étant respectueux de votre question. J'ai seulement enlevé des choses qui lui semblaient inutiles. Depuis que vous avez donné le code que vous étiez en train, et il est évident qu'elle ne fonctionnait pas, alors les gens implicitement savais que vous besoin d'une explication de pourquoi sans avoir à le dire (et maladroitement). Juste essayer d'aider! 🙂
- Evan, est-ce mieux? Je ne veux pas l'embêter. Si vous rollback encore une fois je ne vais pas éditer à nouveau, mais pourriez-vous au moins de conserver le titre & tag édite en place?
- Techniquement, je ne suis pas à l'aide de Javascript à tous, je suis en utilisant v8 (ECMAScript). Mais, j'imagine que la plupart des gens à la recherche, ce sera à la recherche pour le JavaScript, donc je suis bien avec elle.
- N'hésitez pas à ajouter des balises de retour si vous pensez qu'ils appartiennent.
- et pour la postérité: Il est tout à fait possible d'appeler v8 de mise en œuvre de ECMAscript "JavaScript" même si techniquement c'est un abus de langage. Faire la distinction pour tous les cas où il n'était pas Netscape ou Mozilla mise en œuvre serait juste de prendre trop de temps et il n'y a vraiment pas de jolie façon de prononcer "ECMAscript" avec moins de 5 maladroit syllabes. Ne pas oublier que vous pouvez soutenir techniquement l'ECMA spec, mais n'ont toujours quelque chose d'assez différent de JavaScript ou JScript ou que ce soit Chrome/V8 appelle leur version en sorte qu'il n'affirmer que nous sommes au moins dans la même famille d'ECMAscript.
- Je suis en désaccord. C'est source de confusion et de leur permettre de continuer rend la question encore plus confus. Le Javascript n'toutes sortes de trucs cool Ecmascript qui ne fonctionne pas. Java, Eck-Ma -- pas sûr que la syllabe différence. Confondre les deux est l'équivalent de l'appel de C, un sous-ensemble de C++, C++.
- Un aspect déroutant de cette question a été pour moi que la question est un cas particulier, où le groupe est également à l'ensemble appariés expression. Si ce n'est pas le cas, les réponses ont des résultats inattendus, parce qu'elles traitent l'ensemble du match.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez passer d'une fonction à
replace
.Explication
Dans cet exemple, vous passez d'une chaîne à la fonction remplacer. Puisque vous êtes à l'aide de la remplacer syntaxe ($N attrape la Nième capture) vous êtes tout simplement en donnant la même valeur. Le
toUpperCase
est fait tromper parce que vous faites de la chaîne de remplacement majuscules (Qui est un peu inutile, car les$
et un1
personnages n'ont pas de majuscules, de sorte que la valeur de retour sera encore"$1"
).Croire ou de ne pas la sémantique de cette expression sont exactement les mêmes.
$1
pour le premier groupe de capture.Je sais je suis en retard à la fête, mais voici une brève méthode est plus le long des lignes de votre tente.
Alors, où avez-vous aller mal et qu'est-ce que cette nouvelle vaudou?
Problème 1
Comme indiqué précédemment, vous avez été d'essayer de transmettre les résultats d'une méthode appelée en tant que second paramètre de Chaîne de caractères.le prototype.replace(), quand au lieu de cela, vous devriez être en train de passer d'une référence à une fonction
Solution 1
C'est assez facile à résoudre. Enlever simplement les paramètres et les parenthèses va nous donner une référence plutôt que sur l'exécution de la fonction.
Problème 2
Si vous essayez d'exécuter le code maintenant, vous obtiendrez un message d'erreur indiquant que l'indéfini n'est pas une fonction et ne peut donc pas être appelé. C'est parce que la Chaîne.le prototype.toUpperCase.appliquer est en fait une référence à Fonction.le prototype.appliquer() via JavaScript de l'héritage par prototype. Donc, ce que nous sommes en train de faire ressemble plus à ce
Qui n'est évidemment pas ce que nous avons prévu. Comment sait-il à exécuter Fonction.le prototype.appliquer() sur Chaîne de caractères.le prototype.toUpperCase()?
Solution 2
À l'aide de Fonction.le prototype.bind() nous pouvons créer une copie de la Fonction.le prototype.appel avec son contexte spécifiquement String.le prototype.toUpperCase. Nous avons maintenant la suivante
Problème 3
Le dernier problème est que Chaîne de caractères.le prototype.replace() va passer plusieurs arguments à sa fonction de remplacement. Cependant, Fonction.le prototype.appliquer() attend le second paramètre à un tableau mais il récupère une chaîne de caractères ou un nombre (en fonction de si vous utilisez des groupes de capture ou pas). Ce serait la cause d'un argument non valide erreur de liste.
Solution 3
Heureusement, on peut tout simplement remplacer dans Fonction.le prototype.call() (qui accepte un nombre quelconque d'arguments, dont aucun n'a les restrictions de type) pour Fonction.le prototype.appliquer(). Nous voilà arrivés au code de travail!
L'excrétion d'octets!
Personne ne veut de type prototype un tas de fois. Au lieu de cela, nous allons tirer parti du fait que nous avons des objets qui font référence à la même méthodes via l'héritage. La Chaîne de constructeur, étant une fonction, hérite de prototype de la Fonction. Cela signifie que l'on peut remplacer dans la Chaîne.appel pour Fonction.le prototype.appel (en fait, nous pouvons utiliser la Date.appel pour sauver encore plus d'octets, mais c'est moins sémantique).
Nous pouvons également tirer parti de notre variable 'a', car il est le prototype inclut une référence à Chaîne de caractères.le prototype.toUpperCase nous pouvons échange avec un.toUpperCase. C'est la combinaison des 3 solutions ci-dessus et ces octets mesures d'économie qui est la façon dont nous obtenons le code en haut de ce post.
Vieux post, mais il vaut la peine de s'étendre @ChaosPandion réponse pour les autres cas d'utilisation avec plus restreint RegEx. E. g. assurer la
(f)
ou la capture d'un groupe surround avec un format spécifique/z(f)oo/
:Je veux juste mettre en évidence les deux paramètres de
function
rend la recherche d'un format spécifique et repose d'une capture d'un groupe au sein du format possible.SOLUTION
pour remplacer toutes les grup occurrences utilisation
/(f)/g
regexp. Le problème dans votre code:String.prototype.toUpperCase.apply("$1")
et"$1".toUpperCase()
donne"$1"
(essayez dans la console par vous-même) - il ne rien changer et en fait, vous appeler deux foisa.replace( /(f)/, "$1")
(qui d'ailleurs ne change rien).JS:
Donné un dictionnaire (objet, dans ce cas, un
Map
) de la propriété, des valeurs, et à l'aide de.bind()
comme décrit à l'réponsesJS:
À l'aide d'un JavaScript objet ordinaire et avec une fonction définie de retour égalée valeur de la propriété de l'objet, ou de la chaîne d'origine si aucune correspondance n'est trouvée
JS: