1
votes

Comment formater un texte à l'aide de regex en javascript?

J'ai un texte qui a des caractères de format entre accolades.

let regex = /\{([^}]+)\}/g;
let matches = str.match(regex).map(x => x.replace(/[{}]/g, ""));

Je veux changer cela avec les propriétés d'un objet.

var myobj = { name: "x", age: "25" }

Le texte du résultat doit être "Mon nom est x et mon âge a 25 ans!"

Je peux obtenir le nom et l'âge dans le texte en utilisant l'expression régulière.

let str = "My name is {name} and age is {age}!";

correspond est un tableau ["name", "age"]

Mais comment puis-je remplacer par des propriétés d'objet en utilisant regex? Un chemin court est-il possible?


3 commentaires

Juste pour vérifier, est-ce qu'il doit être regex? Un modèle littéral peut le faire plus facilement: `Mon nom est {myobj.name} et mon âge est {myobj.age}!` ou même `Mon nom est {name} et mon âge est { age}! ` si vous vous assurez que name et age sont des variables.


str.replace (regex, (x, y) => myobj [y]? myobj [y]: x)


@VLAZ, j'ai besoin d'une solution regex, je connais votre solution.


3 Réponses :


2
votes

Vous pouvez utiliser la méthode .replace et obtenir la valeur de myobj par clé que vous capturez déjà dans le groupe 1 avec votre regex actuelle:

let str = "My name is {name} and age is {age} {x}! {missing from myobj}";
var myobj = { name: "x", age: "25", x: ""}
let regex = /{([^{}]+)}/g;
console.log( str.replace(regex, (x,y) => myobj[y] !== undefined ? myobj[y] : x) );
// or a bit more modern variation
console.log( str.replace(regex, (x,y) => myobj[y] ?? x) );

Si la clé capturée est présente ( myobj [y] ?? ), la valeur correspondante sera retournée. S'il n'y a pas de clé trouvée avec l'expression régulière dans myobj , la correspondance entière sera retournée ( x ). Si vous devez renvoyer une valeur sans accolades si la clé n'est pas trouvée, utilisez y au lieu de x ici.

Il n'est pas nécessaire de s'échapper { ou } dans le modèle car ils ne peuvent pas être analysés comme un quantificateur limitant (dans ces cas, le moteur JavaScript RegExp effectue une analyse "intelligente").


4 commentaires

myobj [y] || x rend plus propre


@ User863 il peut également se déclencher par accident si le remplacement est une chaîne vide.


@VLAZ Le remplacement est un appelable ici, ce n'est pas une chaîne vide. [^ {}] + correspond à un ou plusieurs caractères, il y aura toujours du texte entre les accolades, donc il n'y aura aucune chance de rechercher une clé de chaîne vide.


@ WiktorStribiżew Je voulais dire si myobj [y] est une chaîne vide, c'est faux, donc il renverra l'espace réservé, au lieu de le supprimer. str = "bonjour {foo}"; myobj = {foo: ""} par exemple.



2
votes

Expression régulière

Vous pouvez utiliser String # replace et spécifiez une fonction en remplacement . Cela vous permettra de remplacer le contenu correspondant s'il correspond à une clé ou de l'ignorer;

function replace({name, age}) {
  return `My name is ${name} and age is ${age}!`;
}

let myobj = { name: "x", age: "25" };

console.log(replace(myobj));

Ou beaucoup plus court si vous utilisez le opérateur de fusion nul ( ?? ) . Il peut ne pas être pris en charge sur les environnements plus anciens, donc le code peut nécessiter une transpilation pour les anciens.

function replace(text, obj) {
  return text.replace(
    /\{([^}]+)\}/g, 
    (fullMatch, capture) => obj[capture] ?? fullMatch
  );
}

let str = "My name is {name} and age is {age}!";
let myobj = { name: "x", age: "25" };

console.log(replace(str, myobj));

console.log(replace("Hello, {location} is {age} years old", myobj));

Modèle littéral

Vous pouvez également simplement ignorer l'expression régulière si c'est toujours la même chaîne, mais les remplacements peuvent différer. Utilisation d'un modèle littéral et déstructuration :

function replace(text, obj) {
  let regex = /\{([^}]+)\}/g;
  
  return text.replace(regex, (fullMatch, capture) => {
    //in case no replacement is found, use the initial as default
    let result = fullMatch; 
    
    //see if we have any replacement for this placeholder
    if (capture in obj) {
      result = obj[capture];
    }
    
    //return the value to be used instead of the placeholder
    return result;
  })
}

let str = "My name is {name} and age is {age}!";
let myobj = { name: "x", age: "25" };

console.log(replace(str, myobj));

console.log(replace("Hello, {location} is {age} years old", myobj));

0 commentaires

1
votes

Vous pouvez l'essayer String.prototype.replace avec une fonction comme paramètre .

let str = "My name is {name} and age is {age}!";
var myobj = { name: "x", age: "25" };
let regex = /\{([^}]+)\}/g;
const res = str.replace(regex, (match, key) => myobj[key] || match);
console.log(res);


0 commentaires