指定したファイルの中から'<'と'>'とで囲まれた部分文字列を抽出したいのですが方法がわかりません。どのようにしたらできるでしょうか?
*ファイルは制御コードが混じっているのでバイナリとして扱わないといけないかもしれません。
よろしくお願い致します。
-------------------------------------------------
open(IN, "test.dat");
open(OUT, "> out.txt");
binmode(IN);
while (<IN>) {
/^<(\w+)>$/;
print OUT "$1\n";
}
close(IN);
close(OUT);
No.1
- 回答日時:
ファイルを全部読んでしまえばいいんじゃないでしょうか? (<> で読むと改行コードで区切れてしまいます)。
それから <[^>]*> のパターンで中味を全部取り出せばいいと思います。例) @data に < > で括られたデータを全て入れる。
open(F, '< ファイル名') or die;
binmode(F);
read(F, $buf, -s F);
close(F);
while ($buf =~ /<([^>]*)>/g) {
push(@data, $1);
}
皆様、ご回答ありがとうございます。
下記のようなデータでテストを行ったところ、下記のような出力結果となりました。
※No.1ソースは下記のようにさせていただきました。
open(IN, '< in.txt') or die;
open(OUT, "> out.txt");
binmode(IN);
read(IN, $buf, -s IN);
while ($buf =~ /<([^>]*)>/g) {
push(@data, "$1\n");
}
print OUT @data;
close(IN);
close(OUT);
●テストデータ
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
abcdef<zzz>abcdef<zzzz>abcdef
zzzz<zzzzz>zzzzzzzz<zzzzz>zzzzzzz
01234567<z
z>01234567
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
●No.1出力結果
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
zzz
zzzz
zzzzz
zzzzz
z
z
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
●No.2出力結果
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
zzz>abcdef<zzzz>abcdef
zzzz<zzzzz>zzzzzzzz<zzzzz>zzzzzzz
01234567<z
z
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
●No.3出力結果
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
zzz
zzzz
zzzzz
zzzzz
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
正確なテストデータをお出ししていなかったため、
皆様異なる条件を設定していただいためか、
出力結果は異なる結果となりました。
No.1様が正確な結果となりました。
条件公開があまく申し訳ございませんでした。
皆様ありがとうございます。
ところで、本当のデータの中にはごみの'<'や'>'も含まれていました。
2パターンの条件を追加したいのですが、やはりどうしてもうまく行きません
●対応する'<'と'>'で抽出し、ごみの'<'や'>'は無視する
○"dafdsa<gfdsg<0000<111>dfa<1111>dsafs>d<d" ⇒ "111"と"1111"のみ抽出
上記が難しいなら
●'<'と'>'の間に'@'がある場合のみ正規なものとする
○"dsafdsa<asf<111@111>afdsafe<> >><<11@11>asdf<a" ⇒ "111@111"と"11@11"のみ抽出
でも構いません。
申し訳ございませんが、お力添えいただけないでしょうか?
よろしくお願い致します。
twinkleluz様、詳細にご丁寧にありがとうございます。徐々にですが、自分で解決する力が養われ、勉強になります。
No.2
- 回答日時:
質問者さんのソースコードでは、以下のような問題があります。
・ファイルを一行ずつ読んでいるので、複数行にまたがる"<"と">"の間の文字列抽出ができない
行ごとの抽出なら問題ありませんが、複数行をまたがる抽出なら、変数にファイルの内容を一度に読み込む必要があります。
Perlには読み込む時の「レコード区切り文字」が変数$/で指定されています。
デフォルトは改行が使われていますが、これを無効にすることでファイルの内容を一度に読むことができます。
undef($/);
・マッチングに使っている正規表現の誤り
/^<(\w+)>$/
これは、「変数の中身が'<'で始まり、その中の文字がすべて半角英数文字で、変数の一番最後が'>'で終わる」ということを表します。
ファイルの中身が'<'で始まり、'>'で終わっていなければならないので、文字列中の'<'と'>'で囲まれた文字は抽出できません。
また、'<''>'の間に制御文字が入っていた場合も抽出できません。
また、\wでは制御コードをマッチングさせることができません。
正しくは、
/<(.+)>/s
でいいと思います。
'.'は改行コードを除くすべての文字にマッチします(制御コード含む)
/sをつけているのは、'.'に改行コードをマッチさせるためです。
なお、制御コードが0x00-0x7Fの間なら、binmodeを使う必要はありません。
修正後のソースは以下のような感じになります。
------------------------------------------
undef($/);
open(IN, "test.dat");
open(OUT, "> out.txt");
while (<IN>) {
/<(.+)>/s;
print OUT "$1\n";
}
close(IN);
close(OUT);
No.3
- 回答日時:
自分ならこうでしょうか。
#2さんの変数に一度に読むテクを借りて。
undef($/);
open(IN, "test.dat");
$_ = <IN>;
open(OUT, "> out.txt");
while (/<(.*?)>/g) {
print OUT "$1\n";
}
close(IN);
close(OUT);
$/='\n'; #一応元に戻しておく
.*? の?は最小マッチです。?がないと、最大マッチとなってしまうので?が必要となります。
No.4ベストアンサー
- 回答日時:
#3 です。
回答にsが抜けてました。while (/<(.*?)>/g) ではなく, while (/<(.*?)>/gs)です。
ごめんなさい。
> ●対応する'<'と'>'で抽出し、ごみの'<'や'>'は無視する
これは<>がネストしてしまった場合等は一番内側の<~>内にしておくという解釈でよろしいでしょうか? 抽出したい<>の中に <や>は入らないということ前提ですが、 while部分を
while(/<([^<>]*)>/sg){
とするとどうでしょう sは複数行にまたがってマッチさせるためのオプションです。binmodeを使っている場合は不要なので /<([^<>]*)>/g でも大丈夫です。
●'<'と'>'の間に'@'がある場合のみ正規なものとする
でよいのなら,
while (/<([^<>]*?@[^<>]*?)>/sg)
とするとどうでしょう。sは上と同じ理由でbinmodeの場合は省いてもかまいません。
--------------
前者と後者でのテスト結果も一応残しておきます。
■ データ
<aa><bb>
<cccc>
<ddd
ddd>
eee<f
fff>
<gggg<hhhh>iiiii<jjj@jjjj>kkkk>
lllll<m<n@nn>ooo<p> >><<qqq@qq>rrr<s
@sss>ttt@uu<vv@vv>wwww>
■前者
aa
bb
cccc
ddd
ddd
f
fff
hhhh
jjj@jjjj
n@nn
p
qqq@qq
s
@sss
vv@vv
■後者
jjj@jjjj
n@nn
qqq@qq
s
@sss
vv@vv
arcsinさん、貴重なお時間をいただき、プログラムの作成、テストまで行っていただき、大変ご親切にありがとうございます。
若干データに予期せぬものがあったりしましたが、教えてもらった後、改良することで、自力解決できました。大変助かりました。ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- C言語・C++・C# [至急]Project Euler:#17Number letter countsコード入力出力解説 2 2022/09/24 02:46
- Perl perlについての質問 2 2022/10/17 15:25
- 英語 文の構造をご教示ください 2 2023/01/01 18:03
- MySQL MYSQL エラー 2 2022/10/18 11:37
- その他(プログラミング・Web制作) atcoder python コードへの助言 2 2022/08/12 15:31
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlのプログラミング 部分入れ...
-
Strawberry Perl for Windows ...
-
アルファベットに付いて質問し...
-
Perlで同じフォルダにある任意...
-
perlでリテラル値はメモリにど...
-
ペプシコーラとコカ・コーラとD...
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
perlで2次元配列をサブルーチ...
-
perlのrequireの動き方について...
-
perlについての質問
-
Blenderについて
-
Perl の外部モジュールの利用方法
-
perl このテキストファイルを簡...
-
Perlでファイルの末尾から指定...
-
秀丸での一括変換について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイルで提出とは?
-
openした後、closeしないでプロ...
-
perlをバージョンアップしたら...
-
INDIRECT 横に再度抽出したい
-
Perl の外部モジュールの利用方法
-
Perlで特定文字列から特定文字...
-
Perlのエラーについてご教授く...
-
bashスクリプト
-
Strawberry Perl for Windows ...
-
perlで2次元配列をサブルーチ...
-
TeraPadエディターの操作方法に...
-
アルファベットに付いて質問し...
-
perlのflock関数でロックをかけ...
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
Wallpaper Engineでおすすめの...
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
perlでリテラル値はメモリにど...
-
画像が表示でnull; this.src
おすすめ情報