2
votes

Utilisation de javascript regex pour supprimer plusieurs barres obliques inverses tout en préservant \ n le caractère spécial

Nous utilisons JS pour charger des données JSON qui ont souvent plusieurs barres obliques inverses avant un caractère de nouvelle ligne. Exemple:

console.log('Even Slashes:');
console.log("\\n".replace(/\\(?=.{2})/g, ''));
console.log('Odd Slashes:');
console.log("\\\n".replace(/\\(?=.{2})/g, ''));

J'ai essayé une variété de modèles RegEx en utilisant replace. "Curieusement", ils semblent fonctionner s'il y a un nombre pair de contre-obliques, mais pas impair.

Cet exemple, avec 2 contre-obliques fonctionne:

"\\\n".replace(/\\(?=.{2})/g, '');

Alors que cet exemple, avec 3 ne fonctionne pas:

"\\n".replace(/\\(?=.{2})/g, '');


6 commentaires

\ n est une séquence d'échappement pour le caractère de nouvelle ligne. \\ est une séquence d'échappement pour la barre oblique inverse. Ainsi, \\ n est une barre oblique inverse suivie d'un n , et \\\ n est une barre oblique inverse suivie d'une nouvelle ligne, et ainsi de suite.


Suivi sur @ p.s.w.g dit. Essayez-vous de supprimer toutes les barres obliques inverses qui précèdent une nouvelle ligne?


Essayez simplement de supprimer \\ ou encore mieux \\ + pour vider la chaîne et cela ne supprimera qu'une ou plusieurs occurrences de littéral \ et cela gagnera ne touchez pas du tout à vos nouvelles lignes si en effet ce sont des nouvelles lignes et non une barre oblique inverse littérale suivie d'un n littéral


@JuanMendes - Oui, j'essaie de supprimer toutes les barres obliques inverses qui précèdent la nouvelle ligne.


@PushpeshKumarRajwanshi, merci mais aucune de ces solutions ne fonctionne.


@shackleton: Cela fonctionne. Laissez-moi vous montrer quelques exemples.


3 Réponses :


1
votes

Je pense que vous essayez de supprimer toutes les contre-obliques qui précèdent une nouvelle ligne: str.replace (/ \\ + \ n / g, "\ n") .

Vous peut être mal compris comment les séquences d'échappement fonctionnent a >:

  • "\\" est une barre oblique inverse

  • "\\ n" est une barre oblique inverse suivie de la lettre n

Consultez le code ci-dessous pour une explication et notez que la sortie de la console de Stack Overflow réencode la chaîne, mais si vous vérifiez les outils de développement réels, il est préférable d'afficher les caractères encodés.

const regex = /\\+\n/g;
// This is "Hello" + [two backslashes] + "nworld"
const evenSlashes = "Hello\\\\nworld";
// This is "Hello" + [two backslashes] + [newline] + "world"
const oddSlashes = "Hello\\\\\nworld";
console.log({
   evenSlashes,
   oddSlashes,
   // Doesn't replace anything because there's no newline on this string
   replacedEvenSlashes: evenSlashes.replace(regex, "\n"),
   // All backslashes before new line are replaced
   replacedOddSlashes: oddSlashes.replace(regex, "\n")
});

 entrez la description de l'image ici


2 commentaires

Merci @Juan! Malheureusement, nous ne pouvons pas être sûrs à 100% qu'il s'échappe correctement. Il peut y avoir n'importe quel nombre de barres obliques inverses (paires ou impaires).


@shackleton Cela n'a pas de sens, il n'y a pas de nouvelle ligne dans le cas pair . Si dans ce cas, il était destiné à être une nouvelle ligne, il est mal encodé, vous ne pouvez pas le réparer après qu'il a été mal encodé car il n'y a aucun moyen de savoir s'il était censé être une barre oblique inverse, une nouvelle ligne ou tout simplement un n



1
votes

Comme je l'ai mentionné dans mon commentaire précédent, vous avez affaire à deux séquences d'échappement différentes ici:

  • \ n est une séquence d'échappement pour le caractère de nouvelle ligne, c'est-à-dire Caractère Unicode 'LINE FEED (LF)' (U + 000A)
  • \\ est une séquence d'échappement pour la barre oblique inverse, c'est-à-dire Caractère Unicode 'REVERSE SOLIDUS' (U + 005C)

Bien que ces séquences d'échappement soient deux caractères dans le code source , elles ne représentent en fait qu'un seul caractère en mémoire.

Observez:

const toEscaped = s => s.toSource().match(/"(.*)"/)[0];
const toHex = s => Array.from(s).map((_, i) => s.charCodeAt(i).toString(16).padStart(2, '0')).join('+');
['\n', '\\n', '\\\n', '\\\\n', '\\\\\n']
  .map(s => ({ a: s, b: s.replace(/\\+[n\n]/g, '\n') }))
  .forEach(({a, b}) => console.log(`${toEscaped(a)} --> ${toHex(b)}`))

Ceci s'applique également aux expressions régulières. Le \ n compte en fait comme un caractère, donc la recherche anticipée (? =. {2}) tentera également de capturer le \ précédent, c'est pourquoi vous voyez peut-être une certaine étrangeté dans le fonctionnement de votre remplacement.

Cependant, en lisant certains de vos commentaires, il semble que vous ayez peut-être affaire à des encodages incorrects. Par exemple, vous pouvez avoir des cas où un utilisateur entre foo \ nbar dans un champ de saisie, qui est interprété comme un littéral \ suivi de n code > (c'est-à-dire "foo \\ nbar" ) et maintenant vous voulez l'interpréter comme un caractère de nouvelle ligne, (par exemple "foo \ nbar" ). Dans ce cas, vous n'essayez pas réellement de supprimer les caractères \ , vous essayez de convertir la séquence de caractères \ + n en \ n .

L'extrait de code suivant montre comment effectuer les substitutions de séquence d'échappement pour \\ et \ n :

const toEscaped = s => s.toSource().match(/"(.*)"/)[0];
const toHex = s => Array.from(s).map((_, i) => s.charCodeAt(i).toString(16).padStart(2, '0')).join('+');
['\n', '\\n', '\\\n', '\\\\n', '\\\\\n']
  .map(s => ({ a: s, b: s.replace(/\\n/g, '\n').replace(/\\\\/g, '\\') }))
  .forEach(({a, b}) => console.log(`${toEscaped(a)} --> ${toHex(b)}`))

Et pour les deux remplacer le "\\ n" par "\ n" et supprimer "\ \ " caractères qui le précèdent essayez quelque chose comme ceci:

const toEscaped = s => s.toSource().match(/"(.*)"/)[0];
['\n', '\\n', '\\\n', '\\\\n', '\\\\\n']
  .forEach(s => console.log(`There are ${s.length} character(s) in ${toEscaped(s)}`))


0 commentaires

1
votes

Pour supprimer tous les échappements échappés d'un texte source, c'est
rechercher: / ([^ \\] | ^) (?: \\\\) + / g remplacer \1


0 commentaires