Comment obtenir la sous-chaîne " It's big \"problem "
en utilisant une expression régulière?
s = ' function(){ return " It\'s big \"problem "; }';
/"(?:[^"\\]|\\.)*"/
Fonctionne dans The Regex Coach et PCRE Workbench.
Exemple de test en JavaScript:
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
Celui-ci provient de nanorc.sample disponible dans de nombreuses distributions Linux. Il est utilisé pour la coloration syntaxique des chaînes de style C
\"(\\.|[^\"])*\"
Selon ePharaoh, la réponse est:
/"([^"\\]*(\\.[^"\\]*)*)"/
Pour que ce qui précède s'applique aux chaînes entre guillemets simples ou doubles, utilisez
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
La plupart des solutions fournies ici utilisent des chemins de répétition alternatifs, à savoir (A | B) *.
Vous pouvez rencontrer des dépassements de pile sur des entrées volumineuses, car certains compilateurs de modèles l'implémentent à l'aide de la récursion.
Java, par exemple: http://bugs.Java.com/bugdatabase/view_bug.do?bug_id=6337993
Quelque chose comme ceci: "(?:[^"\\]*(?:\\.)?)*"
, ou celle fournie par Guy Bedford réduira le nombre d’étapes d’analyse syntaxique en évitant la plupart des débordements de pile.
"(?:\\"|.)*?"
Alterner le \"
et le .
passe sur les guillemets échappés, tandis que le quantificateur paresseux *?
vous assure de ne pas dépasser la fin de la chaîne citée. Fonctionne avec les classes .NET Framework RE
/"(?:[^"\\]++|\\.)*+"/
Tiré directement de man perlre
sur un système Linux sur lequel Perl 5.22.0 est installé . En optimisation, cette expression rationnelle utilise la forme 'possessive' de +
et *
pour empêcher les retours arrière, car on sait auparavant qu'une chaîne sans fermeture la citation ne correspondrait en aucun cas.
Celui-ci fonctionne parfaitement sur PCRE et ne tombe pas avec StackOverflow.
"(.*?[^\\])??((\\\\)+)?+"
Explication:
"
;.*?
{Match fictif}; se terminant par un caractère non d'échappement [^\\]
;(.*?[^\\])??
"
), mais peut être précédée du nombre pair de paires de signes d'échappement (\\\\)+
; et c'est Greedy (!) optionnel: ((\\\\)+)?+
{Matching glouton}, bacause string peut être vide ou sans fin paire./(["\']).*?(?<!\\)(\\\\)*\1/is
devrait fonctionner avec n'importe quelle chaîne citée
en voici un qui fonctionne avec "et" et vous en ajoutez facilement d’autres au début.
("| ') (?: \\\ 1 | [^\1]) *?\1
il utilise la référence arrière (\ 1) qui correspond exactement à ce qui se trouve dans le premier groupe ("ou").
Je me suis trompé à regexpal et je me suis retrouvé avec cette regex: (Ne me demandez pas comment ça marche, je comprends à peine même si je l’ai écrit lol)
"(([^"\\]?(\\\\)?)|(\\")+)+"
J'ai rencontré un problème similaire en essayant de supprimer les chaînes entre guillemets susceptibles d'interférer avec l'analyse de certains fichiers.
Je me suis retrouvé avec une solution en deux étapes qui bat toutes les expressions rationnelles compliquées que vous pouvez proposer:
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
Plus facile à lire et probablement plus efficace.
Si on cherche depuis le début, peut-être que ça peut marcher?
\"((\\\")|[^\\])*\"
Une version plus complète de https://stackoverflow.com/a/10786066/1794894
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
Cette version contient aussi
“
et fermer ”
)Une option qui n'a pas encore été abordée est:
Cela a l'avantage supplémentaire de pouvoir associer correctement les balises ouvertes échappées.
Disons que vous avez la chaîne suivante; String \"this "should" NOT match\" and "this \"should\" match"
ici, \"this "should" NOT match\"
ne devrait pas être apparié et "should"
devrait être . En plus de cela this \"should\" match
devrait être apparié et \"should\"
ne devrait pas.
D'abord un exemple .
// The input string.
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"';
// The RegExp.
const regExp = new RegExp(
// Match close
'([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' +
'((?:' +
// Match escaped close quote
'(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' +
// Match everything thats not the close quote
'(?:(?!\\1).)' +
'){0,})' +
// Match open
'(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))',
'g'
);
// Reverse the matched strings.
matches = myString
// Reverse the string.
.split('').reverse().join('')
// '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS'
// Match the quoted
.match(regExp)
// ['"hctam "\dluohs"\ siht"', '"dluohs"']
// Reverse the matches
.map(x => x.split('').reverse().join(''))
// ['"this \"should\" match"', '"should"']
// Re order the matches
.reverse();
// ['"should"', '"this \"should\" match"']
Ok, maintenant pour expliquer la RegExp . C’est l’expression rationnelle qui peut être facilement décomposée en trois parties. Comme suit:
# Part 1
(['"]) # Match a closing quotation mark " or '
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
# Part 2
((?: # Match inside the quotes
(?: # Match option 1:
\1 # Match the closing quote
(?= # As long as it's followed by
(?:\\\\)* # A pair of escape characters
\\ #
(?![\\]) # As long as that's not followed by an escape
) # and a single escape
)| # OR
(?: # Match option 2:
(?!\1). # Any character that isn't the closing quote
)
)*) # Match the group 0 or more times
# Part 3
(\1) # Match an open quotation mark that is the same as the closing one
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
C’est probablement beaucoup plus clair sous forme d’image: généré avec Regulex de Jex
Image sur github (Visualizer d'expressions régulières JavaScript.) Désolé, ma réputation n'est pas assez grande pour inclure des images, il ne s'agit donc que d'un lien.
Voici un résumé d'un exemple de fonction utilisant ce concept un peu plus avancé: https://Gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js
Il faut se rappeler que les expressions rationnelles ne sont pas une solution miracle pour tout ce qui est string-y. Certaines choses sont plus simples à faire avec un curseur et linéaire, manuel, à la recherche. Un CFL ferait l'affaire assez trivialement, mais il n'y a pas beaucoup d'implémentations de CFL (autant que je sache).