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

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

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

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

5回答

227閲覧

Javaで文字列に含まれる「%n」を「{n-1}」に変換したい

miyabi_k

総合スコア13

Java

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

1グッド

0クリップ

投稿2018/09/12 07:27

編集2018/09/12 07:43

前提・実現したいこと

Javaで文字列に含まれる「%n」を「{n-1}」に変換したいです。
具体的に言うと、
「10点一致しました(%1、%2、%3、%4、%5、%6、%7、%8、%9、%10)」

「10点一致しました({0}、{1}、{2}、{3}、{4}、{5}、{6}、{7}、{8}、{9}」
という変換がしたいです。

正規表現を使って「%n」を抽出することは思いつくのですが、
そこからどのようにn-1して変換すればよいかわからず、困っています。

※「%n」は「%1」~「%99」まで可変です。

A-pZ👍を押しています

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

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

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

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

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

guest

回答5

0

ベストアンサー

こんな感じでしょうか。

Java

1import java.util.regex.*; 2 3class Main { 4 public static void main(String[] args) { 5 String src = "10点一致しました(%1、%2、%3、%4、%5、%6、%7、%8、%9、%10)"; 6 7 String dst = Pattern.compile("%(\d+)") 8 .matcher(src) 9 .replaceAll( 10 m -> String.format( 11 "{%d}", Integer.valueOf(m.group(1)) - 1 12 ) 13 ) 14 ; 15 16 System.out.println(dst); 17 } 18}

実行結果 Wandbox

plain

110点一致しました({0}、{1}、{2}、{3}、{4}、{5}、{6}、{7}、{8}、{9})

Matcher#replaceAll​(Function<MatchResult,String>)

投稿2018/09/12 07:50

編集2018/09/12 07:54
LouiS0616

総合スコア35660

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

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

spookybird

2018/09/12 08:16

Matcher#replaceAll​(Function<MatchResult,String>) これ、Java9で追加されたんですね... 知らなかったー
LouiS0616

2018/09/12 08:25

私も知らなかったのですが、Pythonのように関数を受け取る置換メソッドがあるだろうとアタリをつけて調べたら案の定あったのです。 むしろこんな最近に追加されたものだったのですね。バージョン確認してなかったです。
miyabi_k

2018/09/12 10:22

ご回答いただきありがとうございます。 今回やりたかった事が解決できました。 ありがとうございます。
swordone

2018/09/12 15:35

細かいことを言うなら、Integer.valueOfではなくInteger.parseIntのほうがいいのでは… 減算のために一回アンボクシングが発生します。
LouiS0616

2018/09/12 16:20

@swordone さん 詰めが甘かったです。ご指摘ありがとうございます。
guest

0

あんまりスマートじゃないんですが、Java もっと勉強せねばという思いを込めてとりあえず作ってみたんで載せときますね。
LouiS0616 さんのがスマートでいいですね。

java

1import java.util.regex.Pattern; 2import java.util.regex.Matcher; 3 4class Main { 5 public static void main(String[ ] args) { 6 String original = "10点一致しました(%1、%2、%3、%4、%5、%6、%7、%8、%9、%10)"; 7 String replaced = original; 8 Matcher m = Pattern.compile("%\d+").matcher(original); 9 10 while (m.find()) { 11 String matched = m.group(); 12 int number = Integer.valueOf(matched.split("%")[1]) - 1; 13 replaced = replaced.replaceFirst(matched, "{" + number + "}"); 14 } 15 16 System.out.println(replaced); 17 } 18}

投稿2018/09/12 08:12

spookybird

総合スコア1803

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

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

miyabi_k

2018/09/12 10:24

ご回答いただきありがとうございます。 サンプルコード、参考にさせていただきます。 ありがとうございました。
guest

0

正規表現を使って「%n」を抽出することは思いつくのですが、

そこからどのようにn-1して変換すればよいかわからず、困っています。
「10点一致しました(%1、%2、%3、%4、%5、%6、%7、%8、%9、%10)」

「10点一致しました(・・・)」というのは元データを加工した後のイメージということですよね?
加工前の元データが不明なので、正規表現で「%n」は抽出し取得済みとしてそれ以降の加工部分を書いてみました。

コードと出力結果

投稿2018/09/12 07:52

編集2018/09/12 08:21
opyon

総合スコア1009

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

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

miyabi_k

2018/09/12 10:23

ご回答いただきありがとうございます。 サンプルコード、参考にさせていただきます。 ありがとうございました。
guest

0

replaceを使うのはどうでしょうか。

Java

1文字列.replace(抽出する文字列,置き換える文字列);

追記
ただのreplaceだと該当するものを全部置換してしまうので、
replaceFirstを使用した方がいいですかね。
…って書いている間にもっと良さそうな回答がついてますね。

追記
他の回答者の方に比べれば全然スマートじゃないし汎用性もないけど低評価つけられるほど酷いのか…。
↓こんな使い方を想定。

Java

1String chk = "10点一致しました(%1、%2、%3、%4、%5、%6、%7、%8、%9、%10)"; 2String rplChk = ""; 3for(int i=0;i<99;i++){ 4 rplChk = chk.replaceFirst("%"+(i+1),"{"+i+"}"); 5 chk = rplChk; 6} 7System.out.print(rplChk);

投稿2018/09/12 07:38

編集2018/09/12 08:37
madoka9393

総合スコア992

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

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

退会済みユーザー

退会済みユーザー

2018/09/12 08:44 編集

あ ファーストだから大丈夫か
LouiS0616

2018/09/12 09:00 編集

1から99までの数値が抜けなく重複なく並ぶ、という前提なら問題なさそうですね。 rplChkの役割がちょっとよくわかりませんが。
madoka9393

2018/09/12 09:05

仰る通り、考慮できてないですね…。 >rplChk 態々変数挟む意味ないですねこれ。 chk = chk.replace… でいいやつですね…。
miyabi_k

2018/09/12 10:21

ご回答いただきありがとうございます。 今回は重複は無いのですが、抜けの可能性があるため、ご提示いただいた内容では不十分でした。 ですが、replaceFirstの使い方として参考になりました。 ありがとうございます。
LouiS0616

2018/09/12 10:53

@madoka9393 さん 100から降順にreplaceで全置換していけば問題ないと思います。
madoka9393

2018/09/12 12:46

なるほど! 態々ありがとうございます!
guest

0

質問内容を勘違いして回答してしまったので取消します。

投稿2018/09/12 07:36

編集2018/09/12 07:38
tkturbo

総合スコア5572

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問