Como posso preservar espaços em branco quando eu corresponder e substituir várias palavras em Perl?

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

  •  07-07-2019
  •  | 
  •  

Pergunta

Vamos dizer que eu tenho algum texto original:

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

Eu preciso o texto para coincidir com uma parte dela, dizem: "has a substring"

No entanto, o texto original eo texto correspondente pode ter diferenças de espaço em branco. Por exemplo, o texto de partida pode ser:

has a
substring

ou

has  a substring

e / ou o texto original poderia ser:

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

O que eu preciso do meu programa para a saída é:

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

Eu também preciso para preservar o padrão de espaço em branco no original e apenas adicionar os marcadores de início e fim para ele.

Todas as ideias sobre a maneira de usar Perl expressões regulares para obter isso aconteça? Eu tentei, mas acabou ficando horrivelmente confuso.

Foi útil?

Solução

Já esteve algum tempo desde que eu usei perl expressões regulares, mas que sobre: ??

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

Este seria capturar zero ou mais espaços em branco e caracteres de nova linha entre as palavras. Vai envolver toda a partida com suportes, mantendo a separação originais. Não é automático, mas ela não funciona.

Você pode brincar com isso, como tomar o "has a substring" corda e fazendo uma transformação nele para torná-lo "has\s*a\s*substring" para tornar este um pouco menos dolorosa.

Editar :. Os comentários de Incorporated ysth que o \ s metacharacter corresponde novas linhas e Hobbs correções ao uso meu \ s

Outras dicas

Este padrão irá coincidir com a cadeia de caracteres que você está olhando para encontrar:

(has\s+a\s+substring)

Assim, quando o usuário insere uma seqüência de pesquisa, substituir qualquer espaço em branco na seqüência de pesquisa com \s+ e você tem o seu padrão. O, basta substituir cada jogo com [match starts here]$1[match ends here] onde $1 é o texto correspondente.

Em expressões regulares, você pode usar + para significar "um ou mais". Então, algo como isto

/has\s+a\s+substring/

partidas has seguido por um ou mais espaços em branco caracteres, seguidos por a seguido por um ou mais espaços em branco caracteres, seguido por substring.

Colocá-lo em conjunto com um operador de substituição, você pode dizer:

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 a saída é:

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

A muitos sugeriu, uso \s+ para coincidir com espaços em branco. Aqui está como você faz isso 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]$&[match ends here]/g;

print $original;

Output:

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

Você pode querer escapar qualquer meta-caracteres na cadeia. Se alguém estiver interessado, eu poderia adicioná-lo.

Este é um exemplo de como você poderia fazer isso.

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

Este momento faz nada para verificar a variável $match para caracteres não seguros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top