2008-10-07 6 views
2

Je dois découper toutes les occurrences du modèle '-' qui sont à l'intérieur guillemets simples dans la chaîne longue (en laissant intacts ceux qui sont en dehors des guillemets simples) .Remplacer les modèles qui sont à l'intérieur des délimiteurs en utilisant un appel d'expression régulière

Existe-t-il une manière d'expression régulière? (l'utiliser avec un itérateur de la langue est OK).

Par exemple, en commençant par

"xxxx rt/$ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb" 

Je finirais avec:

"xxxx rt/$ 'dfdffggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g 'ggh' vcbcvb" 

Je suis à la recherche d'une expression rationnelle qui pourrait être exécuté à partir des langues suivantes comme indiqué

  • JavaScript input.replace (/ someregex/g, "")
  • PHP preg_replace ('/ someregex /', "", entrée)
  • python re.sub (r'someregex », "", entrée)
  • Ruby input.gsub (/ someregex /, "")

Répondre

2

J'ai trouvé une autre façon de le faire d'une réponse par Greg Hewgill à Qn138522
Il est basé sur l'utilisation de cette expression régulière (adapté pour contenir le modèle que je cherchais):

--(?=[^\']*'([^']|'[^']*')*$) 

Greg explique:

« ce que cela fait est d'utiliser le match non-capture (?=...) pour vérifier que le caractère x est dans une chaîne entre guillemets Il semble pour certains personnages nonquote jusqu'à. la citation suivante, puis recherche une séquence de caractères simples ou des groupes de caractères entre guillemets, jusqu'à la fin de la chaîne. Cela repose sur votre hypothèse que les citations sont toujours équilibrées. Cela n'est pas très efficace «

Les exemples d'utilisation serait:.

  • JavaScript: input.replace(/--(?=[^']*'([^']|'[^']*')*$)/g, "")
  • PHP: preg_replace('/--(?=[^\']*'([^']|'[^']*')*$)/', "", input)
  • Python: re.sub(r'--(?=[^\']*'([^']|'[^']*')*$)', "", input)
  • Ruby: input.gsub(/--(?=[^\']*'([^']|'[^']*')*$)/, "")

J'ai testé cela pour Ruby et il fournit le résultat souhaité.

+0

Homme vous avez sauvé ma journée ... mais cette regexp ne semble pas fonctionner avec sed ... –

2

Cela ne peut pas être fait avec des expressions régulières, parce que vous devez maintenir l'état si vous êtes entre guillemets simples ou à l'extérieur, et regex est intrinsèquement sans état. (Aussi, si je comprends bien, les guillemets simples peuvent être échappés sans terminer la région "à l'intérieur"). Votre meilleur pari est de parcourir la chaîne caractère par caractère, en gardant un drapeau booléen sur si vous êtes ou non dans une région citée - et supprimez les - de cette façon.

0

Hm. Il pourrait être un moyen en Python s'il n'y a pas apostrophes cité, étant donné qu'il ya le (?(id/nom)oui motif|sans motif) construction dans les expressions régulières, mais il va bien au-dessus ma tête actuellement.

Est-ce que cela aide?

def remove_double_dashes_in_apostrophes(text): 
    return "'".join(
    part.replace("--", "") if (ix&1) else part 
    for ix, part in enumerate(text.split("'"))) 

Cela semble fonctionner pour moi. Ce qu'il fait est de diviser le texte d'entrée en parties sur les apostrophes, et de remplacer le "-" seulement lorsque la partie est impaire (c'est-à-dire qu'il y a eu un nombre impair d'apostrophes avant la partie). Remarque sur "impairs": la numérotation des pièces commence à zéro!

1

Si plier les règles un peu est autorisé, cela pourrait fonctionner:

import re 
p = re.compile(r"((?:^[^']*')?[^']*?(?:'[^']*'[^']*?)*?)(-{2,})") 
txt = "xxxx rt/$ 'dfdf--fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '--ggh--' vcbcvb" 
print re.sub(p, r'\1-', txt) 

Sortie:

xxxx rt/$ 'dfdf-fggh-dfgdfg' ghgh- dddd -- 'dfdf' ghh-g '-ggh-' vcbcvb 

Le regex:

(    # Group 1 
    (?:^[^']*')? # Start of string, up till the first single quote 
    [^']*?  # Inside the single quotes, as few characters as possible 
    (?: 
    '[^']*'  # No double dashes inside theses single quotes, jump to the next. 
    [^']*? 
)*?   # as few as possible 
) 
(-{2,})   # The dashes themselves (Group 2) 

Si là où différents délimiteurs pour le démarrage et fin, vous pouvez utiliser quelque chose comme ceci:

-{2,}(?=[^'`]*`) 

Edit: j'ai réalisé que si la chaîne ne contient pas de guillemets, il correspondra à tous les tirets doubles dans la chaîne. Une façon de le fixer serait de changer

(?:^[^']*')? 

au début de

(?:^[^']*'|(?!^)) 

Mise à jour regex:

((?:^[^']*'|(?!^))[^']*?(?:'[^']*'[^']*?)*?)(-{2,}) 
0

Vous pouvez utiliser le script sed suivant, je crois:

:again 
s/'\(.*\)--\(.*\)'/'\1\2'/g 
t again 

Stockez cela dans af ile (rmdashdash.sed) et faire tout ce que la magie exec dans votre langage de script vous permet de faire l'équivalent shell suivante:

sed -f rmdotdot.sed < fichier contenant vos données d'entrée

Qu'est-ce que le script ne est:

:again < - juste une étiquette

s/'\(.*\)--\(.*\)'/'\1\2'/g

substitut, pour le modèle 'suivi de tout suivi par - suivi de tout suivi de', juste les deux éléments entre guillemets.

t again < - réintroduit la chaîne résultante dans sed. Notez que ce script convertira '----' en '', car il s'agit d'une suite de deux - entre guillemets. Cependant, '---' sera converti en '-'.

Ce n'est pas une école comme la vieille école.

+0

"foo 'bar' - 'baz'" -> "foo 'bar' 'baz'" –

Questions connexes