質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

2回答

1558閲覧

Perl6の正規表現における後読みの中での量指定子の書き方について

jororo0

総合スコア11

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2016/11/25 05:03

編集2016/11/27 10:10

###前提・実現したいこと
Perl6を使って以下のような文を置換させたいのですが、エラーが出て動きません。
Perl6か.NETでないと先読み後読みの中で量指定子が使えないらしいのです。
outerタグの中だけを対象にするとどうしても後読みが必須になるのでこれを実現できる書き方を教えていただけませんか?

これから

XML

1<outer>text1,text2,text3</outer> 2<other>o1,o2,o3</other>

これに

XML

1<outer> 2 <inner>text1</inner> 3 <inner>text2</inner> 4 <inner>text3</inner> 5</outer> 6<other>o1,o2,o3</other>

###発生している問題・エラーメッセージ

エラーメッセージ ===SORRY!=== Error while compiling C:\Users\****\Desktop\Perl6test/replace_co mma.pl6 Unsupported use of /i; in Perl 6 please use :i at C:\Users\****\Desktop\Perl6test/replace_comma.pl6:3 ------> ter outer.[^\,]+>\,<before .\/outer>/</i<HERE>nner>\n\t\t<inner>/;

###該当のソースコード

PHP

1my $t = '<outer>text1,text2,text3</outer>'; 2$t~~s:g/<after outer.[^\,]+>\,<before .\/outer>/</inner>\n\t\t<inner>/; 3$t~~s:g/<after outer.>/\n\t\t<inner>/; 4$t~~s:g/<after .\/outer>/<inner>/\n;

###補足情報(言語/FW/ツール等のバージョンなど)
perl6 -v
This is Rakudo version 2016.07.1 built on MoarVM version 2016.07
implementing Perl 6.c.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/11/25 06:44

関連タグの「PHP」は「Perl」にかえたほうがいいと思います。
jororo0

2016/11/27 11:35

ご指摘ありがとうございます。
guest

回答2

0

この種の処理のほとんどに言えることですが、少数の正規表現でテキスト全体を一気に処理しようとするのではなく、テキストデータの構造を把握した上で少しずつ処理したほうがいいです。

こういう場合、次のような手法が使われます。

  • Perl 6ではgrammerを使うのが一般的です。
    例としてXML::Parser::Tinyなどを見てみて下さい (これが一番よい例だということではなく、探して最初に見つかっただけです。ほかにもあります)。

  • Perl 5だとm/\G ... /gcを使ってトークナイザを書く方法をよく使います。
    perlfaq6「正規表現の中で \G を使うと何が良いのですか?」を読んで下さい。
    実例としてはMIME::Wordsのdecode_mimewords()など (これも最初に見つかっただけです)。

投稿2016/11/25 06:42

編集2016/11/25 06:43
ikedas

総合スコア4317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jororo0

2016/11/27 14:08

回答ありがとうございます。 とりあえずgrammar の書き方から順にみていこうかと思います。
guest

0

エスケープされていないバックスラッシュが正規表現中に出現して、エラーになっていました。
少し形を変えてみましたが、いかがでしょうか?

perl

1my $t = "<outer>text1,text2,text3</outer>\n<other>o1,o2,o3</other>"; 2$t~~s:g/<before .*\/outer>\,/<\/inner>\n\t\t<inner>/; 3$t~~s:g/\<outer\>/\<outer\>\n\t\t<inner>/; 4$t~~s:g/\<\/outer\>/\<\/inner\>\n<\/outer>/;

出力結果

$ perl6 test.p6 <outer> <inner>text1</inner> <inner>text2</inner> <inner>text3</inner> </outer> <other>o1,o2,o3</other>

投稿2016/11/25 06:30

ester41

総合スコア148

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jororo0

2016/11/27 11:35

回答ありがとうございます。 こちらでも動作しました。 しかし、1度目の置換がマッチする理由がよくわかりません。 /outer, ↑のような文に一致すると思います。正規表現では (?<=/outer), ↑のようになると思いますが、動作が違うのでしょうか? また、後出しで申し訳ないのですが、下記のような文の場合は<before .*\/outer>となっているためか期待する結果と違うようです。 <other>o1,o2,o3</other><outer>text1,text2,text3</outer>\n<other>o1,o2,o3</other>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問