2016-11-04 2 views
-1

$ row enthältIch versuche zu verstehen, wie dieser reguläre Ausdruck in Perl erstellt, was es tut

<img alt="1688.jpg" src="http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg" /> 

Nachdem ich die folgende Anweisung

$row =~ s/("(.+?)")(.+?)("(.+?)")/""$3$1/; 

$row enthält <img alt="" src="1688.jpg" />

auszuführen, die ist genau das, was ich will, obwohl ich nicht herausfinden kann, wie die Regex das Folgende bevölkern kann.

$1 -> "1688.jpg"<br> 
$2 -> 1688.jpg<br> 
$3 -> src= (it has a leading space)<br> 
$4 -> "http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg"<br> 
$5 -> http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg<br> 

ich meine, es hätte mich nicht lange fast so ergriffen haben, um es an die Arbeit, wenn ich nur verstanden hätte, wie es die Variable wurde bevölkern. Könnte jemand so freundlich sein, es mir zu erklären?

+1

Verwenden Sie Inline-Code-Markup für die HTML-Tags und Variablennamen in Ihrer Prosa. Ich wollte es beheben, aber ich weiß nicht, ob Ihre Eingabe ' simbabque

+0

Versuchen Sie es mit dem 're 'debug'-Pragma. http://perldoc.perl.org/re.html#'debug'-mode oder setzen Sie Ihr Muster in http://regex101.com – simbabque

Antwort

4

Die Erfassungsgruppen sind von links nach rechts nummeriert (ignorieren Sie die Tatsache, dass einige verschachtelt sind). Angesichts Ihrer Eingabe werden die Capture-Gruppen wie folgt nummeriert:

$row =~ s/("(.+?)")(.+?)("(.+?)")/""$3$1/; 1 2 3 4 5

Auch die ? nach dem .+ bedeutet, dass es die minimale Übereinstimmung kann es um das Muster zu erfüllen, in diesem Fall wird es passen bis zu der erstes Doppelzitat findet es. So können wir sehen, dass es die folgende (ignorieren die einfachen Anführungszeichen) erfasst:

  1. ' "1688.jpg"'
  2. '1688.jpg'
  3. 'src ='
  4. ‚“ http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg „‘
  5. http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg

Da dies eine Zeichenkette Substitution ist, der gesamte Abschnitt der Eingabe, die abgestimmt wurde, wird durch den zweiten Teil ersetzt werden, des Regex-Musters (d.h. ""$3$1). So werden wir (aus den ersten doppelten Anführungszeichen zum letzten doppelten Anführungszeichen) diese ersetzen:

"1688.jpg" src="http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg"

mit: "" src="1688.jpg"

Hoffnung, das hilft.

1

Beginnen Sie einfach mit dem Zählen der Gruppen beginnend mit der linken Klammer, um zu sehen, was erfasst wird. Hier ist eine leicht kommentierte Version:

#!/usr/bin/env perl 

use strict; 
use warnings; 

my $row = '<img alt="1688.jpg" src="http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg" />'; 

#   1 2 2 13 34 5 5 4 
my $re = qr/("(.+?)")(.+?)("(.+?)")/; 

#   12  213 345                54 
# <img alt="1688.jpg" src="http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg" />'; 

$row =~ $re; 
print "\n"; 
print "\$1 => '$1'\n"; 
print "\$2 => '$2'\n"; 
print "\$3 => '$3'\n"; 
print "\$4 => '$4'\n"; 
print "\$5 => '$5'\n"; 

$row =~ s/$re/""$3$1/; 
print $row . "\n"; 

Ausgabe

$1 => '"1688.jpg"' 
$2 => '1688.jpg' 
$3 => ' src=' 
$4 => '"http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg"' 
$5 => 'http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg' 
<img alt="" src="1688.jpg" /> 
+0

Chris & xxfelixxx, Antwort am meisten geschätzt, wie die Regex und Variablen Sinn machen und ich erkenne ich hätte mitkommen können ... $ row = ~ s /"(.+?)"(.+?)((.+?)"/""$ 2 "$ 1" /; – SystemsWiki

0

Da die Menschen vor mir gut erklärt haben, jedes Mal, wenn Sie Klammern verwenden Sie eine Capture-Gruppe erstellen.

Ich finde den besten Weg, um Verwirrung zu vermeiden oder Klammern zu zählen ist es, die Sachen, die Sie nicht benötigen, explizit zu erfassen, indem Sie ?: nach der öffnenden Klammer setzen.

use Data::Dumper; 

my $s = '<img alt="1688.jpg" src="http://res.cloudinary.com/stw/image/upload/v1478118784/1688.jpg" />'; 

my @row = $s =~ /("(.+?)")(.+?)("(.+?)")/; 

# only capture quoted things 
my @row1 = $s =~ /(?:"(.+?)")(?:.+?)(?:"(.+?)")/; 

print Dumper \@row; 
print Dumper \@row1; 
Verwandte Themen