質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

8979閲覧

Javaで「英数は半角に、カナは全角に」をやりたい

masaya_ohashi

総合スコア9210

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2020/03/30 06:19

編集2020/03/30 07:15

前提・実現したいこと

文字列の中から「全角英数→半角英数」「半角カナ→全角カナ」をしたいです。
Java標準のNormalizer、またはicu4jを使えばいいかなと思っていましたが、微妙に望む形と違うので困っています。
他の方法でも「全角英数→半角英数」「半角カナ→全角カナ」が同時に実現できればなんでもいいです。

発生している問題・エラーメッセージ

「特定の文字種だけ全角、半角」にするのがうまくいかない

理想

  • アガパ 012 ABC ㈱アガパ 012 ABC ㈱
クラス処理結果問題
java.text.Normalizernormalize(str, Normalizer.Form.NFKC)アガパ 012 ABC (株)記号等が変換される
com.ibm.icu.text.TransliteratorgetInstance("Halfwidth-Fullwidth").transliterate(str)アガパ 012 ABC ㈱カナが半角になる
com.ibm.icu.text.TransliteratorgetInstance("Fullwidth-Halfwidth").transliterate(str)アガパ 012 ABC ㈱英数が全部半角になってしまうし、記号等の意図しない文字も変換される
com.ibm.icu.text.TransliteratorgetInstance("[:Katakana:];Halfwidth-Fullwidth").transliterate(str)アガパ 012 ABC ㈱半角濁点や半角半濁点が変換されない

補足情報(FW/ツールのバージョンなど)

Java8
icu4j 66.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

こんなのでも宜しければ...

java

1import java.text.Normalizer; 2import java.util.regex.*; 3 4public class Main { 5 public static void main(String[] args) { 6 String s = "アガパ 012 ABC ㈱"; 7 Pattern p = Pattern.compile("([ヲ-゚A-Za-z0-9]+)"); 8 Matcher m = p.matcher(s); 9 StringBuffer sb = new StringBuffer(); 10 while(m.find()) { 11 m.appendReplacement(sb, Normalizer.normalize(m.group(), Normalizer.Form.NFKD)); 12 } 13 System.out.println(m.appendTail(sb)); 14 } 15}

投稿2020/03/30 14:29

編集2020/03/30 14:45
jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2020/03/31 00:07

すごいきれいな形だと思います!ただ、NKFDだと濁音半濁音が分割されていたのでNKFCで使わせてもらおうと思います!
jimbe

2020/03/31 03:48

>NKFDだと濁音半濁音が分割されていた 失礼しました. こちらの表示では合成されていましたので, 中身確認していませんでした.
guest

0

java.text.Normalizer

Normalizer.normalize()を半角カタカナの範囲に適用。仕様に応じて範囲を変えてください。

Java

1import java.text.Normalizer; 2import java.util.function.Function; 3import java.util.function.IntUnaryOperator; 4import java.util.stream.Collectors; 5 6public class WidthConversion { 7 8 static IntUnaryOperator anFull2Half = c -> ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z') ? c + ('A' - 'A') : ('0' <= c && c <= '9') ? c + ('0' - '0') : c; 9 static Function<String,String> kHalf2Full = s -> (s.compareTo("。") >= 0 && s.compareTo("゚") <= 0) ? Normalizer.normalize(s, Normalizer.Form.NFKC) : s; 10 static Function<String, String> convert = s -> s.chars().map(anFull2Half).mapToObj(c -> String.valueOf((char) c)).map(kHalf2Full).collect(Collectors.joining()); 11 12 static void test(Function<String, String> f, String source) { 13 System.out.println(f.apply(source)); 14 } 15 16 public static void main(String[] args) { 17 test(convert,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); 18 test(convert,"アイウエオァィゥェォカキクケコガギグゲゴサシスセソザジズゼゾタチツテトダヂヅデドナニヌネノハヒフヘホバビブベボパピプペポマミムメモヤユヨラリルレロワヲン゙゚ッャュョーヴ。、「」"); 19 } 20 21}

NKFC機能版

Java

1 static Function<String,String> partiallyConvert = 2 s -> (s.compareTo("A") >= 0 && s.compareTo("Z") <= 0 || 3 s.compareTo("a") >= 0 && s.compareTo("z") <= 0 || 4 s.compareTo("0") >= 0 && s.compareTo("9") <= 0 || 5 s.compareTo("。") >= 0 && s.compareTo("゚") <= 0) 6 ? Normalizer.normalize(s, Normalizer.Form.NFKC) : s; 7 8 // NFKC機能を有効にするには、半角カタカナを1文字づつ処理してはならない。 9 // 濁点、半濁点をそれが修飾する文字とセットにする。 10 static BiConsumer<LinkedList<String>,String> withConsonantMark = 11 (a,s) -> { 12 if (!a.isEmpty() && ("゙".equals(s) || "゚".equals(s))) 13 a.add(a.removeLast() + s); 14 else 15 a.add(s); 16 }; 17 18 static Function<String, String> convert = 19 s -> s.chars() 20 .mapToObj(c -> String.valueOf((char) c)) 21 .collect(LinkedList<String>::new, withConsonantMark, List::addAll) 22 .stream() 23 .map(partiallyConvert) 24 .collect(Collectors.joining());

partiallyConvertはjimbeさんの正規表現に近くなりました。

投稿2020/03/30 14:01

編集2020/03/31 06:24
xebme

総合スコア1090

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2020/03/31 00:06

ラムダ使うのは僕好みなのですが、最終的な形が濁音半濁音がUnicodeの分割文字になってしまっていたので、申し訳ないですが別の方をベストアンサーにしたいと思います。
xebme

2020/03/31 06:18

NKFCが機能しないのは、濁点、半濁点が修飾する文字とセットで処理されないから。修正版をあげます。
guest

0

作ってみました。

class HanZen { final static char[] ktab = ("ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテト" + "ナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン").toCharArray(); final static char[] ptab = ("................111111111111111.....22222...............").toCharArray(); public static String conv(String s) { int n = s.length(), j = 0; char p = 0, t[] = new char[n]; for (int i = 0; i < n; i++) { char c = s.charAt(i); if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') { t[j++] = (char)(c - ('A' - 'A')); p = 0; } else if (c >= 'ヲ' && c <= 'ン') { t[j++] = ktab[c-'ヲ']; p = ptab[c-'ヲ']; } else if (c == '゙' && p >= '1') { t[--j] = (char)(t[j++] + 1); p = 0; } else if (c == '゚' && p == '2') { t[--j] = (char)(t[j++] + 2); p = 0; } else { t[j++] = c; p = 0; } } return new String(t, 0, j); } } class Main { public static void main(String[] args) { String s = "abc,abc. はばぱ、ハバパ。"; System.out.println(s); System.out.println(HanZen.conv(s)); } }

追記
全角数字の変換が抜けていました。
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {

if (c>='A' && c<='Z' || c>='a' && c<='z' || c>='0' && c<='9') {
に修正してください。

投稿2020/03/30 10:30

編集2020/03/30 14:48
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2020/03/31 00:05

文字コードを数字として扱って引き算でオフセットを取る原始的なやり方、かつ濁音半濁音をしっかりサポートしてるのはすごいと思いました。
guest

0

万能薬はなかなかない。ルールが独特ならシコシコやるしかないとおもいます。

java

1import java.util.Arrays; 2public class Hoge { 3 private static final String[][] table = { 4 {"ア", "ア"}, 5 {"イ", "イ"}, 6 {"ガ", "ガ"}, 7 {"ネ", "ネ"}, 8 {"ン", "ン"}, 9 }; 10 private static String conv(final String input) { 11 return 12 Arrays.stream(table) 13 .reduce( 14 input, 15 (text, t) -> text.replace(t[0], t[1]), 16 (a, b) -> null); 17 } 18 public static void main(final String[] argss) { 19 final String input = "アガネイロ"; 20 final String out = conv(input); 21 System.out.println(String.format("%s -> %s", input, out)); 22 } 23} 24// アガネイロ -> アガネイロ

投稿2020/03/30 07:02

編集2020/03/30 08:13
shiketa

総合スコア4061

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2020/03/30 07:04

うーん…それしかないですかね…もう少し回答待ちしたいと思います。
shiketa

2020/03/30 07:09

`com.ibm.icu.text.Transliterator#getInstance("Halfwidth-Fullwidth").transliterate(str)`と書いて、あとで見たヒトがぱっと理解してくれるような環境ならいいのでしょうが、なかなか...(^^;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問