75709


次のようなデータがあり、予め変数に代入されているものとします。

[code]

    （置き換えしたいリスト以外にも任意のデータを含む場合あり）
    HOGEHOGEHOGE
    -果物<
    りんご
    ぶどう
    メロン
    >
    
    \():;.'"#
    ?><@`ABCABC
    12345
    
    -os<
    Microsoft Windows
    Mac OSX
    GNU/Linux
    BSD
    >
    
    -timezone<
    (UTC+09:00) Osaka, Sapporo, Tokyo
    (UTC+09:00) Seoul
    (UTC-07:00) Pacific Time (US & Canada)
    (UTC+08:00) Taipei
    (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi
    >
    あいうえお漢字アイウエオｱｲｳｴｵ
    
[/code]

例えばここから[ **置き換え範囲として「-os <」から「>」まで**
]を指定して置き換え対象文字列として次のような文字列を変数から読み込み、指定するとします。

[code]

    Android
    iOS
    Blackberry
    Ubuntu Touch
    
[/code]

その場合、得たい出力は次の通りです。

[code]

    （置き換えしたいリスト以外にも任意のデータを含む場合あり）
    HOGEHOGEHOGE
    -果物<
    りんご
    ぶどう
    メロン
    >
    
    \():;.'"#
    ?><@`ABCABC
    12345
    
    -os<
    Android
    iOS
    Blackberry
    Ubuntu Touch
    >
    
    -timezone<
    (UTC+09:00) Osaka, Sapporo, Tokyo
    (UTC+09:00) Seoul
    (UTC-07:00) Pacific Time (US & Canada)
    (UTC+08:00) Taipei
    (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi
    >
    あいうえお漢字アイウエオｱｲｳｴｵ
    
[/code]

尚、「timezone」や、「GNU/Linux」のように正規表現における特殊文字や「果物」のようにマルチバイト文字が置き換え前、及び、置き換え対象のいずれの変数にも含まれる可能性があるため変数内の文字列は正規表現ではなく平文の文字列として扱いたいです。

sed等で試行錯誤してみましたが特殊文字や空白をうまく処理できなかったりとどうもうまく行きません。  
ご存知の方がいらっしゃたらお力をお貸しください。


CC BY-SA 4.0
2021-05-06T17:11:36.543
75706
2021-05-13T04:59:38.657
2021-05-07T00:16:21.590
3060
45141
question
正規表現 perl sed
正規表現 (sed や Perlなど) で複数行間の選択範囲内を置き換えたい


以下ではシェルスクリプト + Perl で処理を行っています。

[code]

    text=$(cat <<'EOT'
    （置き換えしたいリスト以外にも任意のデータを含む場合あり）
    HOGEHOGEHOGE
    -果物<
    りんご
    ぶどう
    メロン
    >
    
    \():;.'"#
    ?><@`ABCABC
    12345
    
    -os<
    Microsoft Windows
    Mac OSX
    GNU/Linux
    BSD
    >
    
    -timezone<
    (UTC+09:00) Osaka, Sapporo, Tokyo
    (UTC+09:00) Seoul
    (UTC-07:00) Pacific Time (US & Canada)
    (UTC+08:00) Taipei
    (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi
    >
    あいうえお漢字アイウエオｱｲｳｴｵ
    EOT
    )
    
    replaced=$(cat <<'EOT'
    Android
    iOS
    Blackberry
    Ubuntu Touch
    EOT
    )
    
    echo "$text" | perl -0777 -pe 's/((\A|\n)-os<\n)(.|\n)+?(\n>(\Z|\n))/$1'"${replaced}"'$4/;'
    
[/code]


CC BY-SA 4.0
2021-05-06T19:59:27.230
75709
2021-05-06T19:59:27.230
75706
answer


「正規表現 (sed や Perlなど)」ということなので, Pythonで行ってみました  
もちろん, 回答ついてる perlのものとは(たぶん)別の正規表現のはずです

[code]

    import re
    print(re.sub(r'(?<=-os<)[^>]*(?=>)', new_str, text_str, flags=re.M))
    
    # あるいは正規表現パターンオブジェクトを利用する場合 (の文字列探索のみ)
    # chg = re.compile(r'(?<=-os<)[^>]*(?=>)', re.M)
    # m = chg.search(text_str)
    # if m:
    #   print(m[0])
    
[/code]


CC BY-SA 4.0
2021-05-07T05:25:52.783
75715
2021-05-07T05:25:52.783
43025
75706
answer


参考までに、(POSIX) sed で実行する場合には次です。

[code]

    #!/bin/sh
    
    replacement_values='Android
    iOS
    Blackberry
    Ubuntu Touch'
    
    escaped_for_sed_replacement=$(
        printf '%s\n' "$replacement_values" |
            sed -e '$!s/$/\\/' )
    
    sed_script() {
        printf '
    /^-os<$/,/^>$/ c\
    -os<\
    %s\
    >' "$escaped_for_sed_replacement"
    }
    
    cat <<'EOT' | sed -e "$(sed_script)"
    （置き換えしたいリスト以外にも任意のデータを含む場合あり）
    HOGEHOGEHOGE
    -果物<
    りんご
    ぶどう
    メロン
    >
    
    \():;.'"#
    ?><@`ABCABC
    12345
    
    -os<
    Microsoft Windows
    Mac OSX
    GNU/Linux
    BSD
    >
    
    -timezone<
    (UTC+09:00) Osaka, Sapporo, Tokyo
    (UTC+09:00) Seoul
    (UTC-07:00) Pacific Time (US & Canada)
    (UTC+08:00) Taipei
    (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi
    >
    あいうえお漢字アイウエオｱｲｳｴｵ
    EOT
    
[/code]


CC BY-SA 4.0
2021-05-11T11:25:36.273
75784
2021-05-13T04:59:38.657
2021-05-13T04:59:38.657
754
754
75706
answer