sed - 一致しない括弧を一致させない方法

sed - 一致しない括弧を一致させない方法

括弧内の行でのみどうすればよいですか?

たとえば、「.is」行を変更し、角かっこを追加したいが閉じていない角かっこを含む行は変更しないとします。

だからこれらが変わりました。

this_thing.is 24  ->   (this_thing).is 24
that.is 50        ->   (that).is 50
a[23].is == 10    ->     a[23].is == 10
a.is true         ->   (this_thing).is 24
this_thing.is 24  ->   (this_thing).is 24

しかし、これらはそうではありません:

this_thing.is (24
((that).is 50
(a[23].is == 10
a.is ( true
(this_thing.is 24

理想的には両方ではない(いいえ)

a{.is true
this_thing{.is 24

まさか)

a[.is true
this_thing[.is 24 

/.is/のある一致がありますが、一致しない角括弧をどのように一致しますか?

ベストアンサー1

個人的に、私の正規表現がこのレベルの複雑さに近づいている場合は、タスク全体をPerlに切り替えます。これは、複数の開いた中かっこ/丸括弧/中括弧を処理します。

$ perl -ne '@open=/[\[({]/g; @close=/[)\]}]/g; 
             if($#close == $#open){s/(.+?)\.is/($1).is/} print' file

またはより簡単には、次のようになります。

$ perl -pne 's/(.+?)\.is/($1).is/ if $#{/[\[({]/g} == $#{/[)\]}]/g}' file

またはより完全に、同様の状況を処理する次のようになります[}(しかし、同様の状況ではまだ失敗します)()。

  $ perl -pne '@osqb=/\[/g; @csqb=/\]/g; 
               @ocb=/\{/g; @ccb=/\}/g; 
               @op=/\(/g; @cp=/\)/g;
               if($#osqb == $#csqb && $#ocb==$#ccb && $#op == $#cp){
                    s/(.+?)\.is/($1).is/
               }' file

あなたの例を実行すると印刷されます

(this_thing).is 24
(that).is 50      
(a[23]).is == 10 
(a).is true      
(this_thing).is 24
this_thing.is (24
((that).is 50
(a[23].is == 10
a.is ( true
(this_thing.is 24
a{.is true
this_thing{.is 24
a[.is true
this_thing[.is 24 

説明する

  • perl -ne:入力ファイルを1行ずつ処理し、指定された-nスクリプトを実行します-e
  • @open=/[\[({]/g;:開いているすべての文字の外観を見つけ、結果を名前付き配列に保存します@open
  • @close=/[)\]}]/g;:上記と同じですが、グリフをオフにするために使用されます。
  • if($#close == $#open):左グリフ数が右グリフ数と同じ場合(つまり、括弧などがある場合)...
  • s/(.+?)\.is/($1).is/.is:...thenは、括弧内の自分で終わる最も短い文字列を置き換えます。
  • 最後はprint角かっこの外にあり、置き換えるかどうかにかかわらず実行されます。

おすすめ記事