文字種を表す正規表現について
とりあえず、質問の前半に回答しますね。
次の前提で考えます。
- GNU sedを使う。
- POSIX準拠の機能だけ使う。拡張正規表現は使わない。GNU拡張仕様は原則として使わない。
-- POSIXでのsedの仕様はこちら。
-- GNU sedのマニュアルはこちら。
- 入出力の文字コードをUTF-8とする。
-- マルチバイト文字の扱いが簡単なので、UTF-8にしておきます (ほかのShift_JISやEUC-JPなどの文字コードでも工夫すればできますが、そこは本題ではないので)。
-- 当然、sedが実行するスクリプトもUTF-8で作成しなければなりません。
正規表現の書きかたとしては、(a) マッチングの対象をASCIIとその全角形に限定する場合と、(b) マルチバイト対応した場合とが考えられます。
(a) 対象をASCIIとその全角形に限定
sedを起動する際に次のようにしてCロケールの下で起動することで、マルチバイト対応を無効にします。
$ LANG=C sed -f スクリプトファイル 入力ファイル
特定の一文字を表す正規表現は次のように書けます。
数字だけ
([0-9]|0|1|2|3|4|5|6|7|8|9)
アルファベッドだけ
([A-Za-z]|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)
その他は略。
説明します。この場合、sedがマルチバイト文字を認識していないため、全角形の英数字や記号は各々が3バイトの文字列と認識されます。ですので [0-90-9] のように書いても意図した通りの結果にはなりません。選択の正規表現 (...|...|... ) を使って、あり得る文字をすべて列挙する必要があります。
(b) マルチバイト対応
sedを起動する際に次のようにして特定のロケールを指定することで、マルチバイト対応を有効にします。なお、ロケールの文字コードもUTF-8にしなければなりません。
$ LANG=ja_JP.UTF8 sed -f スクリプトファイル 入力ファイル
特定の一文字を表す正規表現は次のように書けます。
記号だけ
[[:punct:]]
数字だけ
[0-90-9]
英字だけ
[A-Za-zA-Za-z]
数字と記号だけ
[0-90-9[:punct:]]
数字と英字だけ
[0-9A-Za-z0-9A-Za-z]
数字と英字と記号だけ
[0-9A-Za-z0-9A-Za-z[:punct:]]
説明します。マルチバイト対応しており、日本語ロケールの文字を認識できるので、[...] の中に全角形の文字を書けます。
また[...] の中に書かれた [:punct:] はPOSIXの文字クラス式で、記号である文字を表します。ただし、文字クラス式がどんなものにマッチするかは、OS毎のロケールの実装によりますので、直感的には記号と思えないようなものがマッチする場合があるかもしれません。
他の文字クラス式を使うこともできます。たとえば私の環境 (CentOS 7.2) で日本語ロケール (ja_JP.UTF8) で確認したところ、[:alpha:] や [:alnum:] は全角形のラテン文字にもマッチするだけでなく、アクセント付きのラテン文字 (「À」など) にもマッチしてくれます。ただ、これらはキリル文字、ギリシャ文字、漢字にまでもマッチしまいましたした。要するに私の環境では、[:alpha:] は「数字や記号や空白でないもの」全般にマッチするようです。
また数字についても、[:digit:] という文字クラス式を使うことができます。ただし私の環境では、全角形の数字にマッチしませんでした。