%20%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82.png)
私は次のことに苦労しています。Mac ターミナルで次のようなコマンドを使用して正規表現をテストしています。
echo 'inputstring' | sed (-E) '/s///g'
次のような正規表現を作成しようとしています:
- 単語が文字「o」で終わる場合のみ、次のようになります。
- この単語の最後の「o」を削除します
- この単語の「i」という文字をすべて「a」に置き換えます
この場合、入力文字列はでありfilo fililo felo fale
、期待される出力はfal falal fel fale
削除または置換のいずれかを実行する正規表現を作成できますが、それらを組み合わせる方法がわかりません。それらの間にセミコロンを入れると、条件部分をどのように入れるかわかりません。
また、「単語の末尾」の位置を定義するのにも問題があります。 を使用しました\b
が、機能しないようです ($
文字列の末尾の場合とは異なります)。
答え1
私はこれに使用しませんsed
が、これが学習のための練習である場合はsed
、次のようなループを実行します。
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a\1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/\1\2/
ta
s/ $//'
- 最初の行では、行末に空白を追加して、行末を単語末と同じように扱えるようにしています。最後の行では、後でその空白を削除します。
s
3 行目のコマンドは、 で終わる単語内の の出現を検索し、i
にo
置き換えますa
。このt
コマンドは、 マークに戻って、で終わるすべての単語内で:a
これを繰り返します。i
o
- 5 行目では、末尾
o
と別のループが削除されます。 で終わる単語からはoo
、両方が削除されることに注意してください。これが望ましいかどうかは不明です。
参考のためだけに、一致した部分だけを保存し、残りを破棄するという意味のコマンドのオプションsed
をサポートするバージョンを使用します。また、置換内の をホールド スペースの内容に置き換えることも認識します。これにより、タスクが 1 行で済みます。o
s
\h
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/\1\2/o;T;y/i/a/;x;s//\h/;ba'
答え2
ぎこちないこのような場合には、より正確で柔軟性があります。
awk '{ for(i=1;i<=NF;i++)
if ($i~/o$/) { sub(/o$/,"",$i); gsub("i","a",$i) } }1' <<<"filo fililo felo fale"
出力:
fal falal fel fale
代替パイソンコマンドラインアプローチ:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"\b(\S+)o\b", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
答え3
これが Python でできるかどうかはわかりませんsed
(おそらくできないと思います) が、Python では非常に簡単にできます。まさに必要なことを実行するスクリプトは次のとおりです。
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(\s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
次のように実行できます:
echo 'filo fililo felo fale' | python modify_strings.py
そして、次の出力が生成されます (希望どおり)。
ファル ファラル フェル ファレ
本当にsed
関与したい場合は、シェル スクリプトを少し追加することで、おそらく目的を達成できるでしょう。次のbash
スクリプトのようになります。
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"${word}"; then
echo -n "${word} " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "${word} ";
fi;
done
echo
このスクリプトは次のように呼び出します:
bash modify-strings.bash filo fililo felo fale