Come posso conservare gli spazi bianchi quando abbino e sostituisco più parole in Perl?

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

  •  07-07-2019
  •  | 
  •  

Domanda

Diciamo che ho del testo originale:

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

Ho bisogno che il testo corrisponda a una parte di esso, ad esempio: " ha una sottostringa " ;.

Tuttavia, il testo originale e la stringa corrispondente potrebbero presentare differenze di spazio. Ad esempio, il testo della corrispondenza potrebbe essere:

has a
substring

o

has  a substring

e / o il testo originale potrebbe essere:

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

Ciò di cui ho bisogno per l'output del mio programma è:

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

Devo anche preservare il motivo degli spazi bianchi nell'originale e aggiungere solo i marcatori di inizio e fine.

Qualche idea su come usare le regex del Perl per far sì che ciò accada? Ci ho provato, ma alla fine mi sono confuso orribilmente.

È stato utile?

Soluzione

È passato del tempo da quando ho usato le espressioni regolari perl, ma che dire di:

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

Questo catturerebbe zero o più spazi bianchi e nuovi caratteri tra le parole. Avvolgerà l'intera partita con parentesi mantenendo la separazione originale. Non è automatico, ma funziona.

Puoi giocare con questo, come prendere la stringa " ha una sottostringa " e fare una trasformazione su di essa per renderla " ha \ s * a \ s * sottostringa " ; per renderlo un po 'meno doloroso.

MODIFICA : incorporati commenti di ysth secondo cui il metacarattere corrisponde alle nuove righe e modifica le correzioni per il mio utilizzo.

Altri suggerimenti

Questo modello corrisponderà alla stringa che stai cercando di trovare:

(has\s+a\s+substring)

Quindi, quando l'utente inserisce una stringa di ricerca, sostituisci qualsiasi spazio bianco nella stringa di ricerca con \ s + e avrai il tuo modello. Sostituisci ogni corrispondenza con [la partita inizia qui] $ 1 [la partita finisce qui] dove $ 1 è il testo corrispondente.

Nei regex, puoi usare + per indicare "uno o più." Quindi qualcosa del genere

/has\s+a\s+substring/

corrisponde a ha seguito da uno o più caratteri di spazi bianchi, seguito da a seguito da uno o più caratteri di spazi bianchi, seguito da sottostringa .

Mettendolo insieme a un operatore di sostituzione, puoi dire:

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;

E l'output è:

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

Molti hanno suggerito di usare \ s + per abbinare gli spazi bianchi. Ecco come lo fai automaticamente:

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]<*>amp;[match ends here]/g;

print $original;

Output:

  

ecco alcuni testi che [la partita inizia qui] ha una sottostringa [la partita finisce qui] che mi interessa incorporare in esso.

Potresti voler sfuggire a qualsiasi meta-carattere nella stringa. Se qualcuno è interessato, potrei aggiungerlo.

Questo è un esempio di come potresti farlo.

#! /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/;
}

Questo attualmente fa di tutto per controllare la variabile $ match per caratteri non sicuri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top