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

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

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

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

6171閲覧

C#で正規表現を使用して、小文字⇔大文字変換をする方法

soi013

総合スコア149

.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/05/19 13:36

編集2020/05/19 14:31

前提・実現したいこと

C#で正規表現(System.Text.RegularExpressions.Regex)を用いて大文字・小文字変換する方法を教えて下さい。

Regexクラスを用いて、大文字・小文字を区別せず検索する方法などはわかるのですが、マッチした文字列を小文字・大文字に変更する方法がわかりません。

ユーザーからの入力と期待される結果の例を示します。

patternreplacesourceresult
例1"C#""C++""C#大好き!""C++大好き!"
例2"(.)""\u$1""123abc""123ABC"

入力例1はRegexでできます。
入力例2はサクラエディタの変換機能例から
https://qiita.com/take333/items/106fde0cdd3cac3c5b68

System.Text.RegularExpressions.Regexではない、nugetライブラリなどで実現できるなら、それでも結構です。

該当のソースコード

以下のような形で、実行時にユーザーからの入力に基づいて文字列の置換を行いたいです。

C#

1static void Main(string[] args) 2{ 3 Console.WriteLine("Input Target Pattern"); 4 var targetPattern = Console.ReadLine(); 5 Console.WriteLine("Input Replace Pattern"); 6 var replacePattern = Console.ReadLine(); 7 8 var regex = new Regex(targetPattern); 9 10 while (true) 11 { 12 Console.WriteLine("Input Source Text"); 13 var sourceText = Console.ReadLine(); 14 var replacedText = regex.Replace(sourceText, replacePattern); 15 Console.WriteLine($"Replaced {sourceText} -> {replacedText}"); 16 Console.WriteLine(); 17 } 18}

試したこと

stringのToLower()またはToUpper()で大文字・小文字変換ができるのはわかりますが、実行時にユーザーからの入力で柔軟に変更するためには正規表現で統一できると助かります。

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

C# 8
.NET Core 3.1
Visual Studio 2019

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

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

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

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

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

maisumakun

2020/05/19 13:41

えっと、質問の意図がわからないのですが。 (ユーザーが入力したパターンで置換を行う、だけなら、大文字小文字はパターンを入力するユーザーが考えればいいだけなので、コードを書く分には関係ないかと思います)
Zuishin

2020/05/19 13:43

正規表現だと柔軟になるということはないと思います。 正規表現でも確かにできますが、それよりも文字列と文字配列は相互に変換できるので、まず文字列を文字配列に直し、前から順に見ていって、大文字なら小文字、小文字なら大文字に変換し、それを文字列に直すのが簡単だと思います。 LINQ が使えるなら使ってください。それだと一行で済みます。
soi013

2020/05/19 13:45

特定の文字列の小文字⇔大文字を切り替えるだけなら、たしかにユーザーに指定してもらえば良いです。そちらの用途がほとんどです。 ただ、「すべての小文字を大文字に変えたい」という動作を実現させるとすると a→A, b→B,,,,,z→Zみたいにパターン27回入力する必要が出てしまいます。 それをユーザーさせるのは無理があるなぁと思いまして。
Zuishin

2020/05/19 13:46

すべての小文字を大文字に変えたいなら ToUpper で十分だと思いますが。
Zuishin

2020/05/19 13:54

これはもしかしてアカウントを間違えて質問しちゃったパターンかな?
soi013

2020/05/19 13:56

@Zuishin 常に小文字→大文字やその逆なら、たしかにToUpperなどを使うのですが、それを正規表現と一緒にあつかう方法はありますでしょうか。 理想としては、以下のようなイメージですかね。 var regex =new Regex("[a-z]") ; regex.Replace("123abc456", "/U"); //123ABC456 > これはもしかしてアカウントを間違えて質問しちゃったパターンかな? ?とくに間違えてはいないです?
Zuishin

2020/05/19 14:02

正規表現の置換でコールバックを指定すればできると思いますが、なぜそれがしたいのかが全くわかりません。ToUpper に対する優位性があるように見えませんが、どのような入力を想定していますか? 例えば、ユーザーが正規表現と置換コマンドを入力して、ファイルか何かの内容を置換するということですか?
soi013

2020/05/19 14:10

> 例えば、ユーザーが正規表現と置換コマンドを入力して、ファイルか何かの内容を置換するということですか? はい、そういうアプリケーションを作ろうとしています。 ユーザーからの入力例1 pattern: "C#" replace: "C++" source: "C#大好き!" result: "C++大好き!" ユーザーからの入力例2 pattern: "(.)" replace: "\u$1" source: "123abc" result: "123ABC" 2はサクラエディタの変換機能例から https://qiita.com/take333/items/106fde0cdd3cac3c5b68
Zuishin

2020/05/19 14:12 編集

普通に Regex の input と pattern と replacement に渡せばいいのではないですか?
soi013

2020/05/19 14:13

入力例2は、質問のソースコードで実行すると結果が `\u1\u2\u3\ua\ub\uc`となります。
Zuishin

2020/05/19 14:19

入力例 2 をちゃんと見ていませんでした。なるほど。だったらこれが使えると思います。 https://docs.microsoft.com/ja-jp/dotnet/api/system.text.regularexpressions.regex.replace?view=netcore-3.1#System_Text_RegularExpressions_Regex_Replace_System_String_System_String_System_Text_RegularExpressions_MatchEvaluator_System_Text_RegularExpressions_RegexOptions_ ユーザーの入力した replace を解析して独自のコマンドに変換し、それにしたがってコールバックを走らせればいいでしょう。解析部分は当然自分で作る必要があります。
soi013

2020/05/19 14:35

了解しました。 ありがとうございます。 できれば回答欄に書いていただけますでしょうか、回答済みにマークしたいので。
guest

回答2

0

ベストアンサー

一部仕様が違います。"\u$1" の場合は、最初のグループを小文字にし、"\U$1" の場合は最初のグループを大文字にします。

C#

1using System; 2using System.Text.RegularExpressions; 3 4namespace ConsoleApp1 5{ 6 class Program 7 { 8 static string Prompt(string message) 9 { 10 Console.WriteLine(message); 11 return Console.ReadLine(); 12 } 13 14 static MatchEvaluator ConvertToMatchEvaluator(string s) 15 { 16 var m = Regex.Match(s, @"^\([uU])$(\d+)"); 17 if (m.Success) 18 { 19 var group = int.Parse(m.Groups[2].Value); 20 return m.Groups[1].Value == "U" 21 ? (MatchEvaluator)(match => match.Groups[group].Value.ToUpper()) 22 : (match => match.Groups[group].Value.ToLower()); 23 } 24 else 25 { 26 return (MatchEvaluator)(_ => s); 27 } 28 } 29 30 static void Main() 31 { 32 while (true) 33 { 34 var input = Prompt("対象となる文字列を入力してください"); 35 var pattern = Prompt("パターンを入力してください"); 36 var replacement = Prompt("置換先文字列を入力してください"); 37 38 var matchEvaluator = ConvertToMatchEvaluator(replacement); 39 Console.WriteLine(Regex.Replace(input, pattern, matchEvaluator, RegexOptions.None)); 40 } 41 } 42 } 43} 44

投稿2020/05/19 14:48

Zuishin

総合スコア28669

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

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

soi013

2020/05/19 15:03

具体的なコードを示してくださり、ありがとうございます。 なるほど、置換文字列にたいしても、Regexで評価してMatchEvaluatorを条件分岐しているのですね。 Microsoftの例よりもわかりやすかったです。
Zuishin

2020/05/19 15:07 編集

サンプルなので正規表現で簡単に解析しましたが、ここを本格的に作りこめば計算式や単位変換などもっと複雑な置換もできると思いますので、あとは自分で実装してください。
guest

0

C#

1"123abc456".ToUpper(); 2 3//結果:123ABC456

これでダメな理由を教えてほしい。


コメント見て追記

常に小文字→大文字やその逆なら、たしかにToUpperなどを使うのですが、それを正規表現と一緒にあつかう方法はありますでしょうか。

抱えている問題が上記のような結果を得ることでないのだとしたら、質問内容を変更してその目的や具体例を示してください。

ご質問の件に関してはこれで解決できるはずなので。


読み返して追記

実行時にユーザーからの入力で柔軟に変更するためには正規表現で統一できると助かります。

「ユーザーからの入力で柔軟に変更」というのは小文字→大文字というパターン以外ですか?
具体例がないとイメージが湧きません。
何を入力させるつもりなんでしょうか?

投稿2020/05/19 14:03

編集2020/05/19 14:08
gentaro

総合スコア8947

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

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

soi013

2020/05/19 14:16

わかりにくくて、申し訳ありません。 > 「ユーザーからの入力で柔軟に変更」というのは小文字→大文字というパターン以外ですか? > 具体例がないとイメージが湧きません。 Zuishinさんへの回答にも書きましたが、ユーザーの入力と期待する動作の例を書きます。 ユーザーからの入力例1 pattern: "C#" replace: "C++" source: "C#大好き!" result: "C++大好き!" ユーザーからの入力例2 pattern: "(.)" replace: "\u$1" source: "123abc" result: "123ABC"
gentaro

2020/05/19 14:30

あぁ、なるほど。 要するに.NETのRegexでパターンへ「\u$1」入力時にサクラエディタと同じ動作をさせるにはどうしたら良いのか、という質問ということですか。 であれば、もうZuishinさんがコメントされているので、こちらの回答は無視してください。
soi013

2020/05/19 14:35

わかりました。回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問