Perlで複数の単語に一致して置換するときに空白を保持するにはどうすればよいですか?
-
07-07-2019 - |
質問
元のテキストがあるとしましょう:
here is some text that has a substring that I'm interested in embedded in it.
テキストの一部に一致するテキストが必要です。たとえば、「サブストリングがあります
"」。
ただし、元のテキストと一致する文字列には空白の違いがある場合があります。たとえば、一致テキストは次のようになります。
has a substring
または
has a substring
および/または元のテキストは次のようになります。
here is some text that has a substring that I'm interested in embedded in it.
出力するプログラムに必要なものは次のとおりです。
here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.
また、元の空白パターンを保存し、開始マーカーと終了マーカーを追加する必要があります。
Perlの正規表現を使用してこれを実現する方法についてのアイデアはありますか?試しましたが、恐ろしく混乱してしまいました。
解決
perlの正規表現を使用してからしばらく経ちましたが、どうですか:
$match = s/(has\s+a\s+substring)/[$1]/ig
これにより、単語間のゼロ個以上の空白文字と改行文字がキャプチャされます。元の分離を維持しながら、一致全体をブラケットでラップします。自動ではありませんが、動作します。
文字列" has a substring"
を取得し、それを変換して" has \ s * a \ s * substring&quotにするなど、これでゲームをプレイできます;
を使用して、これをもう少し簡単にします。
編集:\ sメタキャラクターが私の\ sの使用法に対する改行とホッブスの修正に一致するというysthのコメントを組み込みました。
他のヒント
このパターンは、探している文字列と一致します。
(has\s+a\s+substring)
したがって、ユーザーが検索文字列を入力すると、検索文字列内の空白が \ s +
に置き換えられ、パターンが作成されます。すべての一致を [match starts here] $ 1 [match ends here]
に置き換えます。 $ 1
は一致したテキストです。
正規表現では、 +
を使用して「1つ以上」を意味できます。このようなもの
/has\s+a\s+substring/
has
の後に1つ以上の空白文字が続き、 a
の後に1つ以上の空白文字が続き、部分文字列
が一致します。
置換演算子と組み合わせて、次のように言うことができます:
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;
そして出力は:
here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.
多くの人が示唆しているように、 \ s +
を使用して空白を一致させます。自動で行う方法は次のとおりです。
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;
出力:
ここに[一致はここから始まる]サブストリングがある[一致はここから終わる]というテキストがあります。
文字列内のメタ文字をエスケープしたい場合があります。誰かが興味を持っている場合は、追加できます。
これはあなたがそれを行う方法の例です。
#! /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/;
}
これは現在、 $ match
変数の安全でない文字をチェックするために何でもします。