アカウント名:
パスワード:
(\d)(?=[[:alpha:]]+\s*)
(?<=[[:alpha:]]+\s*)(\d)
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
人生unstable -- あるハッカー
『詳説正規表現 第3版』を読むっ!! (スコア:1)
本を会社に置いてきたのでうろ覚えで申し訳ないのだが…
(?=S) と (?<=S) という特殊なグルーピング処理があるらしい。
どちらも「マッチングカーソルを動かさずに」マッチングを取る、という効能がある。
たとえば 3 on という文があったとする。 という正規表現はこの3とマッチするのに使えるのだそうだ。で、なおかつ、次に正規表現マッチングを開始するのは3の後ろにあるスペース(なりなんなり)、になる。逆に on 3 の場合は でマッチする。ここでのポイントは、on が何か別の正規表現ですでにマッチングとして消費されていても関係ない、と言うこと。
微妙に間違っていたらゴメン。なんとなく、(?<= と (?= が正しいような逆だったような…
.
というわけで私の曖昧模糊とした記憶に頼るのではなく、「詳説 正規表現 第3版 [amazon.co.jp]」を読みましょう。 (ぉぃっ!!
fjの教祖様
Re:『詳説正規表現 第3版』を読むっ!! (スコア:1)
ご紹介ありがとうございます。
いただいてばかりではいけませんので、Javaで実装したコードを書いておきます。
Perlだと、もしかしてコア部分は数行で書けたりするんでしょうか。
package tategaki;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* 横書き用の文章を、縦書き用に変換するコンバータ。<BR>
* 現在のところ、半角数字を漢数字に変換する機能のみ実装済み。<BR>
* 引数にテキストファイル名(ファイル内の文字コードはUTF-8)を取る。<BR>
* 変換済みのテキストは標準出力にアウトプットされる。<BR>
* <ol>
* <li>変換後のテキストには「十」や「百」は含まない。
* <li>数字の前後にアルファベットがある場合には、半角数字のままにする。<BR>
* </ol>
* このルールは、アルファベットと数字の間にスペースがあっても適用される。
* @author WindVoice
*/
public class Tategaki {
BufferedReader file = null;
StringBuffer buffer = new StringBuffer();
/**
* アルファベットとして認識させる正規表現パターン。
*/
Pattern regex_alphabet = Pattern.compile("[a-zA-z]");
/**
* 数値として認識させる正規表現パターン。<BR>
* 半角スペースを混ぜることで、「3 on 3」の数字が変換されない
* ようにするルールを実装できる。
*/
Pattern regex_number = Pattern.compile("[\\d ]");
/**
* 変換テーブル。
* 半角スペースを半角スペースに変換するのがルール2を適用するコツ。
*/
static final String[][] number = {
{"1", "一"}, {"2", "二"}, {"3", "三"}, {"4", "四"}, {"5","五"},
{"6", "六"}, {"7", "七"}, {"8", "八"}, {"9", "九"}, {"0","〇"},
{" ", " "}
};
public Tategaki(String filename) {
try{
file = new BufferedReader( new FileReader(filename) );
}catch(IOException e ){
e.printStackTrace();
}
}
public static void main( String args[]){
Tategaki t = new Tategaki(args[0]);
t.execute();
}
private void execute() {
while( true ){
buffer.delete(0, buffer.length());
try{
String s = file.readLine();
if( s == null ){ break; }
buffer.append( s );
}catch(IOException e){
e.printStackTrace();
System.exit(1);
}
System.out.println(henkan(buffer).toString());
}
}
/**
* 変換ルールのコア部分。
* @param line 入力文字列
* @return 変換済みの文字列
*/
private StringBuffer henkan(StringBuffer line) {
boolean pre_alphabet = false;
for( int i = 0; i < line.length(); i++){
char c = line.charAt(i);
if( isAlphabet(c) ){
pre_alphabet = true;
}else if( isNumber(c) ){
for(int j=1; i+j<line.length(); j++){
c = line.charAt(i+j);
if( ! isNumber(c) ){
if( !pre_alphabet && !isAlphabet(c) ){
replaceKanji( i, i+j, line );
}
pre_alphabet = isAlphabet(c);
i += j;
break;
}
}
}else{
pre_alphabet = false;
}
}
return line;
}
/**
* 変換テーブルに従って文字を置換する。
* @param start 変換を開始する位置(この位置を含む)
* @param end 変換を終了する位置(この位置を含まない)
* @param line 変換対象となる文字列
*/
private void replaceKanji(int start, int end, StringBuffer line) {
for( int i=start; i<end; i++ ){
for( int j = 0; j < number.length; j++ ){
if( Character.toString(line.charAt(i)).equals(number[j][0])){
line = line.replace(i, i+1, number[j][1]);
break;
}
}
}
}
private boolean isNumber(char c) {
return regex_number.matcher(Character.toString(c)).matches();
}
private boolean isAlphabet( char c ){
return regex_alphabet.matcher(Character.toString(c)).matches();
}
}
人生は七転び八起き、一日は早寝早起き
Re:『詳説正規表現 第3版』を読むっ!! (スコア:1)
かなり快適になった縦書き変換クラスTategakiを載せておきます。
----- Tategaki.java -----
package tategaki;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* 横書き用の文章を、縦書き用に変換するコンバータ。<BR>
* 現在のところ、半角数字を漢数字に変換する機能のみ実装済み。<BR>
* 引数にテキストファイル名(ファイル内の文字コードUTF-8)を取る。<BR>
* 変換済みのテキストは標準出力にアウトプットされる。<BR>
* <ol>
* <li>変換後のテキストには「十」や「百」は含まない。
* <li>数字の前後にアルファベットがある場合には、半角数字のままにする。
* </ol>
* このルールは、アルファベットと数字の間にスペースがあっても適用される。
* @author WindVoice
*/
public class Tategaki {
BufferedReader file = null;
StringBuffer buffer = new StringBuffer();
/**
* 全角英数字として認識させる正規表現パターン。
*/
Pattern regex_ZenkakuEisuuji = Pattern.compile("[a-zA-Z0-9]");
/**
* アルファベットとして認識させる正規表現パターン。
*/
Pattern regex_Alphabet = Pattern.compile("[a-zA-z]");
/**
* 数値として認識させる正規表現パターン。<BR>
* 半角スペースを混ぜることで、「3 on 3」の数字が変換されない
* ようにするルールを実装できる。
*/
Pattern regex_Number = Pattern.compile("[\\d0123456789 ]");
/**
* 改行すべき行末かどうかを判定する正規表現パターン。
*/
Pattern regex_Gyoumatsu = Pattern.compile("[。、」!?)…― 』-]$");
/**
* 改行すべき行頭かどうかを判定する正規表現パターン。
*/
Pattern regex_Gyoutou = Pattern.compile("^[(「『 ]");
/**
* 変換テーブル。
* 半角スペースを半角スペースに変換するのがルール2を適用するコツ。
*/
static final String[][] henkan_table = {
{"1", "一"}, {"2", "二"}, {"3", "三"}, {"4", "四"}, {"5","五"},
{"6", "六"}, {"7", "七"}, {"8", "八"}, {"9", "九"}, {"0","〇"},
{" ", " "}
};
static final String[][] zenkaku_hankaku_table = {
{"1", "1"}, {"2", "2"}, {"3", "3"}, {"4", "4"}, {"5","5"},
{"6", "6"}, {"7", "7"}, {"8", "8"}, {"9", "9"}, {"0","0"},
{"a", "a"}, {"b", "b"}, {"c", "c"}, {"d", "d"}, {"e","e"},
{"f", "f"}, {"g", "g"}, {"h", "h"}, {"i", "i"}, {"j","j"},
{"k", "k"}, {"l", "l"}, {"m", "m"}, {"n", "n"}, {"o","o"},
{"p", "p"}, {"q", "q"}, {"r", "r"}, {"s", "s"}, {"t","t"},
{"u", "u"}, {"v", "v"}, {"w", "w"}, {"x", "x"}, {"y","y"},
{"z", "z"}, {"A", "A"}, {"B", "B"}, {"C", "C"}, {"D","D"},
{"E", "E"}, {"F", "F"}, {"G", "G"}, {"H", "H"}, {"I","I"},
{"J", "J"}, {"K", "K"}, {"L", "L"}, {"M", "M"}, {"N","N"},
{"O", "O"}, {"P", "P"}, {"Q", "Q"}, {"R", "R"}, {"S","S"},
{"T", "T"}, {"U", "U"}, {"V", "V"}, {"W", "W"}, {"X","X"},
{"Y", "Y"}, {"Z", "Z"},
{" ", " "}
};
public Tategaki(String filename) {
try{
file = new BufferedReader( new FileReader(filename) );
}catch(IOException e ){
e.printStackTrace();
}
}
public static void main( String args[]){
Tategaki t = new Tategaki(args[0]);
t.execute();
}
private void execute() {
boolean nextGyoumatsuKaigyou = false;
boolean kaigyouOnly = false;
人生は七転び八起き、一日は早寝早起き