マッチした文字列のみ残す


『エルドライブ【élDLIVE】』
宇宙警察っていうと『宇宙刑事ギャバン』を思い出しまが、男の中の男ギャバンとは正反対のような弱々しい男子中学生が主人公です。おそらく主人公が少しずつ強くなっていくストーリーなんでしょう。ギャバンは、魔空空間の中に自ら飛び込んで、敵と戦って現実世界に影響しないようにしてたと記憶してますが、宙太は周囲はお構いなしに戦っているようです。まだ1話目なのでよくわかっていませんが。1話では今のところ宙太の良さがまったく分かりません。謎の宇宙人?ドルーが共生するのにマッチ(適合)した体を持ってるってところぐらいでしょうか(ちなみにギャバンの使ってた電子星獣は「ドル」という名前でした)。気になるのは、同じクラスの女子美鈴。宙太にとても厳しいです。今後どのような関係になっていくのかだけが楽しみです。

さてマッチといえば、正規表現です。
Perlで置換するとき、言語仕様にs///が組み込まれているのでコードが短くて済みます。しかし置換にs///が万能かと言いうと、そうでもないですよね。
マッチする文字列のみ残すケースを考えてみましょう。まず、置換前の文字列を適当に作っておき、

takk@deb83:~$ seq 30 | pr -t10Jl1
1       2       3       4       5       6       7       8       9       10
11      12      13      14      15      16      17      18      19      20
21      22      23      24      25      26      27      28      29      30
takk@deb83:~$ 

この中から6がつく数字の列のみ置換で残すことにします。

takk@deb83:~$ seq 30 | pr -t10Jl1 | perl -pe 's/^.*\t(\d*6).*$/$1/'
6
16
26
takk@deb83:~$ 

このケースでは、s///で十分です。

では、4と6がつく数字の列ならどうでしょうか。

takk@deb83:~$ seq 30 | pr -t10Jl1 | perl -pe 's/^.*\t(\d*[64]).*/$1/g'
6
16
26
takk@deb83:~$ 

gオプションをつけたところで、2つは抽出しません。当然ですね。

()でグルーピングしなければ以下のように置換できます。(縦に並んでしまいましたが)

takk@deb83:~$ seq 30 | pr -t10Jl1 | perl -ne 's/\d*[64]/print"$&\n"/ge'
4
6
14
16
24
26
takk@deb83:~$ 

別の例を作ります。ランダムな数字を160個。

takk@deb83:~$ seq 160 | perl -pe 's/^.*$/int rand(1000)/ge' | pr -t8J | tee data
958	702	692	308	468	820	617	253
526	746	569	105	754	893	572	142
542	276	4	782	971	128	951	523
435	920	431	623	116	369	721	903
721	665	730	907	39	889	970	365
985	724	675	619	940	984	323	185
541	122	386	173	429	266	263	263
630	690	873	116	742	270	420	397
59	218	990	459	323	333	912	617
637	628	749	556	458	852	150	477
547	548	916	914	785	995	558	652
416	246	585	648	836	973	562	474
16	716	326	525	572	181	5	816
595	36	737	239	170	416	948	221
795	284	281	654	920	813	747	479
329	104	169	647	956	192	749	891
598	812	370	171	847	400	221	334
316	453	910	754	938	177	403	188
566	995	376	987	27	312	990	306
281	134	909	587	222	650	965	434
takk@deb83:~$ 

このランダムな数字のデータ、dataファイルから、7百番代の数字のみ置換で残してみます。

takk@deb83:~$ perl -ne 'while($_ =~ /7\d\d/g){print"$& ";}print"\n"' data
702 
746 754 
782 
721 
721 730 
724 

742 

749 
785 

716 
737 
795 747 
749 

754 


takk@deb83:~$ 

whileの{}の中で、マッチした文字列一つ一つに対する処理をすることができます。

もっと簡単に書くと、

takk@deb83:~$ perl -ne '@s=/7\d\d/g;print"@s\n";' data
702
746 754
782
721
721 730
724

742

749
785

716
737
795 747
749

754


takk@deb83:~$ 

配列にマッチ文字列が格納されているので、好きに加工して使うことができますね。

コメント

タイトルとURLをコピーしました