2016-09-28 3 views
1

Hintergrund

Suchen Perioden mit Dollar-Zeichen im Text zu ersetzen, die durch Dollar-Zeichen begrenzt ist (nie Spanning Linien). Zum Beispiel:regex Muster kombinieren Gruppen in begrenzten Zeichenfolgen übereinstimmen

Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$. 

Problem

Die following regex fast funktioniert, aber ist zu einfach:

/([[:alnum:]])\.([[:alnum:]])/g 

Wenn ein Spiel außerhalb der Begrenzungszeichen vorhanden ist ($), dann wird zu viel ersetzt .

Die folgende Regex:

/\$.*?\$/g 

Matches and groups die begrenzten Zeichenfolgen:

Namen: annie.bettie.cindy.dannie.ellie $ $. Nur $ a $ Namen. $ a.b.c.d.e.f $.

Frage

Wie kombiniere ich die beiden regulären Ausdrücke so, dass die Perioden kann durch eine andere Zeichenfolge ersetzt werden? Zum Beispiel:

Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$. 

Letztlich wird sich:

Names: `r v$annie$bettie$cindy$dannie$ellie`. Only `r v$a` names. `r v$a$b$c$d$e$f`. 

Das Problem Ich habe ist, um die begrenzten Punkten übereinstimmen.

Der reguläre Ausdruck wird von einem terminal running bash an peded.

+2

Vielleicht [Dieses SO thread] (http://stackoverflow.com/questions/25241413/pass-the- Matched-value-to-a-function-and-replace-with-the-return-Wert) kann etwas Licht werfen. –

+1

Können Sie Ihre erwartete Ausgabe erklären? problem statement sagte, dass Sie '.' mit '$' innerhalb '$ sometext $' pattern ersetzen müssen. Insbesondere bekomme ich den '' 'rv''' Teil sowie das fehlende' $ 'am Ende des Musters nicht – Sundeep

+0

@Sundeep: Das Ziel ist es, eine Regex zu erstellen, die einfache [Pandoc] (http://pandoc.org/) YAML Variablenreferenzen zu den leistungsfähigeren Inline [knitr] (http://yihui.name/knitr/) konvertiert Ausdrücke. –

Antwort

1

Dies könnte für Sie arbeiten (GNU sed):

sed -r ':a;s/^(([^$]*\$[^$.]*\$)*[^$]*\$[^$.]*)\./\1\n/;ta;s/(\$[^$]*)\$/`r v\1`/g;y/\n/$/' file 

alle Perioden durch eine Zeilenumbrüche innerhalb der Gruppen ersetzen. Fügen Sie Gruppen-Präfixe und Suffix-Literale ein und übersetzen Sie dann die Zeilenumbrüche in Dollar.

1
$ cat ip.txt 
Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$. 

$ perl -pe ' 
BEGIN 
{ 
    sub f 
    { 
     $a = $_[0] =~ tr/./$/r; 
     $a =~ s/^/`r v/; 
     $a =~ s/.$/`/; 
     return $a; 
    } 
} 
s/\$.*?\$/f($&)/ge 
' ip.txt 
Names: `r v$annie$bettie$cindy$dannie$ellie`. Only `r v$a` names. `r v$a$b$c$d$e$f`. 
  • Das Unterprogramm f führt die notwendige Transformation für $sometext$ strings - ersten . zu $ transkribieren, dann eine Schnur zu Anfang hinzufügen und schließlich letzte Zeichen entfernen mit dem erforderlichen Format
    • Das Unterprogramm zu ersetzen ist Setzen Sie einen BEGIN Block, der vor der Verarbeitung der Eingabedatei Zeile für Zeile
  • ausgeführt wird
  • s/\$.*?\$/f($&)/ge wird das $sometext$ Muster extrahieren und an f Subroutine weitergeben.Perl weiß es zu nennen freundlicher Genehmigung der e flag
  • -p Schaltmittel-Eingangsleitung, nachdem alle Befehle
  • gedruckt wird