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

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

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

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Perl

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

zsh

zshは、UNIX系OSのシェルの1つです。 cshやksn系のコマンドライン編集機能も実装されたシェルです。

Q&A

解決済

2回答

444閲覧

正規表現のパターンの繰り返しでマッチした部分が\1に次々と上書きされてしまう

var

総合スコア20

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Perl

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

zsh

zshは、UNIX系OSのシェルの1つです。 cshやksn系のコマンドライン編集機能も実装されたシェルです。

0グッド

0クリップ

投稿2020/07/09 06:33

以下のような文字列が標準入力で渡されます。
文字列がスペースで区切られていて、個数は不明ですが、最低でも6個(str6まで)は必ず存在します。
区切りのスペースは1つとは限らず、2個以上繋がって1つの区切りになっている可能性があります。

text

1str1 str2 str3 str4 str5 str6 str7 str8 str9 ...

この文字列を、str4からstr6を逆順にし、str7以降はそのままにしたいと考えています。
以下のようにするとできましたが、長いので、

zsh

1cat a.txt | perl -p -e 's/^([^ ]+ +)([^ ]+ +)([^ ]+ +)([^ ]+ +)([^ ]+ +)([^ ]+ +)/\1\2\3\6\5\4/g'

このように同じ部分を繰り返しにしてみたところ、\1がどんどん上書きされるだけで、\2以降にはマッチした部分が入らなくなってしまいました。

zsh

1cat a.txt | perl -p -e 's/^([^ ]+ +){6}/\1\2\3\6\5\4/g'

これを防ぐ方法はないでしょうか。

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

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

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

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

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

Zuishin

2020/07/09 07:24 編集

長さが不定なら正規表現を使わず split() で配列に分割して join で組み立てなおした方が簡単なのでは?
var

2020/07/09 07:23

ご回答ありがとうございます。試してみたいと思います。
guest

回答2

0

正規表現のキャプチャーは括弧の数に対応するので、\2以降キャプチャーされないのは必然です。
少なくとも6個の文字列が保証されるなら、長くても修正前の正規表現が妥当です。

ただ6番目の([^ ]+ +)は、([^ ]+( +|$))でないと、文字列が6個の場合、6個目の文字列にマッチしなくなります。

蛇足ですが、TABも区切り扱いとして良いなら、半角スペースをメタキャラ\sで表現した方が読みやすいですね。
([^\s]+\s+)([^\s]+\s+)([^\s]+\s+)([^\s]+\s+)([^\s]+\s+)([^\s]+(\s+|$))
より長くなりますが。。。

投稿2020/07/09 07:20

DreamTheater

総合スコア1095

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

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

var

2020/07/09 07:22

ご回答ありがとうございます。大変参考になりました。
guest

0

ベストアンサー

正規表現における括弧によるグルーピングのルールはシンプルで、開き括弧(が出現するたびに左から順番に\1,\2,...と番号がつけられるというものです。

質問の内容では(は一つしか使われていないので、\1だけが定義されていて\2以降は未定義のままです。

普通に考えればZuishinさんが言うようにsplitすればいいのですが、スペースも保全したいということであれば、gオプションをつけてマッチングした結果を使うことになるでしょう。

$_ = 'str1 str2 str3 str4 str5 str6 str7 str8 str9'; @a = /(\S+\s+)/g; print join('', @a[0,1,2,5,4,3,6..$#a]),"\n";

投稿2020/07/09 07:11

KojiDoi

総合スコア13692

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

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

var

2020/07/09 07:23

ご回答ありがとうございます。大変参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問