Wie kann ich Leerzeichen bewahren, wenn ich mehrere Wörter in Perl entsprechen und ersetzen?

StackOverflow https://stackoverflow.com/questions/1425023

  •  07-07-2019
  •  | 
  •  

Frage

Nehmen wir an, ich habe einige Originaltext:

here is some text that has a substring that I'm interested in embedded in it.

ich den Text brauche einen Teil davon zu entsprechen, sagen: "has a substring"

Allerdings kann der ursprüngliche Text und der passende String Leerzeichen Unterschiede. Zum Beispiel könnte das Spiel Text sein:

has a
substring

oder

has  a substring

und / oder der ursprüngliche Text könnte sein:

here is some
text that has
a substring that I'm interested in embedded in it.

Was ich brauche mein Programm Ausgabe lautet:

here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.

Ich brauche auch das Leerzeichen-Muster im Original zu bewahren und nur den Start- und End-Marker, um es hinzuzufügen.

Alle Ideen über einen Weg Perl verwenden Regexes dies zu bekommen passieren? Ich habe versucht, aber am Ende immer schrecklich verwirrt.

War es hilfreich?

Lösung

Sie waren bereits einige Zeit, seit ich Perl reguläre Ausdrücke verwendet habe, aber was ist:

$match = s/(has\s+a\s+substring)/[$1]/ig

Dies würde erfassen null oder mehr Leerzeichen und Zeilenumbrüche zwischen den Worten. Es wird das gesamte Spiel mit Klammern wickeln, während der ursprüngliche Trennung beibehalten wird. Es ist nicht automatisch, aber es funktioniert.

Sie können Spiele mit diesem spielen, wie der Zeichenfolge "has a substring" nehmen und dabei eine Transformation auf, um es zu machen "has\s*a\s*substring" dies etwas weniger schmerzhaft zu machen.

Bearbeiten . Incorporated ysth Kommentare, dass die \ s metacharacter Spiele Zeilenumbrüche und hobbs Korrekturen an meiner \ s Nutzung

Andere Tipps

Dieses Muster wird mit der Zeichenfolge übereinstimmen, die Sie suchen zu finden:

(has\s+a\s+substring)

Also, wenn der Benutzer einen Suchbegriff eingibt, ersetzt alle Leerzeichen in der Suchzeichenfolge mit \s+ und Sie haben Ihr Muster. Das, ersetzen Sie einfach jedes Spiel mit [match starts here]$1[match ends here] wo $1 ist der angepasste Text.

In Regexes können Sie + verwenden, um bedeuten „ein oder mehrere“. So etwas wie diese

/has\s+a\s+substring/

passt has gefolgt von einem oder mehreren Leerzeichen Zeichen, gefolgt von a gefolgt von einem oder mehreren Leerzeichen Zeichen, von substring gefolgt.

es zusammen mit einem Substitutions Operator Einlochen, kann man sagen:

my $str = "here is some text that has     a  substring that I'm interested in embedded in it.";
$str =~ s/(has\s+a\s+substring)/\[match starts here]$1\[match ends here]/gs;

print $str;

Und der Ausgang ist:

here is some text that [match starts here]has     a  substring[match ends here] that I'm interested in embedded in it.

Eine viele hat vorgeschlagen, die Verwendung \s+ zu Leerzeichen entsprechen. Hier ist, wie Sie es tun automatisch:

my $original = "here is some text that has a substring that I'm interested in embedded in it.";
my $search = "has a\nsubstring";

my $re = $search;
$re =~ s/\s+/\\s+/g;

$original =~ s/\b$re\b/[match starts here]$&[match ends here]/g;

print $original;

Ausgabe:

  

here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.

Sie können keine Meta-Zeichen in der Zeichenfolge entkommen wollen. Wenn jemand interessiert ist, könnte ich hinzufügen.

Dies ist ein Beispiel dafür, wie Sie das tun können.

#! /opt/perl/bin/perl
use strict;
use warnings;

my $submatch = "has a\nsubstring";

my $str = "
here is some
text that has
a substring that I'm interested in, embedded in it.
";

print substr_match($str, $submatch), "\n";

sub substr_match{
  my($string,$match) = @_;

  $match =~ s/\s+/\\s+/g;

  # This isn't safe the way it is now, you will need to sanitize $match
  $string =~ /\b$match\b/;
}

Das zur Zeit etwas tut die $match Variable für unsichere Zeichen zu überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top