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

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

新規登録して質問してみよう
ただいま回答率
85.37%
C#

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

Q&A

解決済

2回答

2950閲覧

C# 文字列のカウント(サロゲートペアで構成されている文字列)

EleAco

総合スコア15

C#

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

1グッド

1クリップ

投稿2021/09/24 13:38

編集2021/09/27 03:58

C#で入力された文字列をカウントする方法を教えていただきたいです。

しかし、入力される値は????‍????‍????‍????や????‍????などサロゲートペアで構成されている文字列です。
「今日は家族で旅行に行った????‍????‍????‍????」これを.Lengthでカウントすると23カウントです
そうではなく、みた通りの13文字としてカウントしたいです。
良いやり方があれば教えてくださいよろしくお願い致します????‍♂️

SurferOnWwwさんの回答を元に記述した内容

C#

1 2string s = "今日は家族で旅行に行った????‍????‍????‍????"; 3StringInfo si = new StringInfo(s); 4int count = si.LengthInTextElements;

変数countの中身は19でした。

平日はすぐに返事できます。

Zuishin👍を押しています

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

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

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

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

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

ikadzuchi

2021/09/24 22:59

本題に関係ないですけど、33カウントにも14文字にも見えませんが、何か間違っていませんか?
退会済みユーザー

退会済みユーザー

2021/09/26 00:12

質問者さん、無言ですが、回答が出ているのでそれらに対するフィードバックを書きましょう。役に立った/立たなかったぐらいはすぐ返せるはず。役に立たなかったなら、どこがダメだったかを書くと、より質問者さんが期待する答えに近いものが出てくるかも。とにかく無言で放置は NG です。
EleAco

2021/09/27 01:58

ikadzuchiさん 間違えです 申し訳ございません 今日は家族で旅行に行った????‍????‍????‍???? は.Lengthにて23カウント 見た目の文字カウントは13カウントでした
EleAco

2021/09/27 02:00

SurferOnWwwさん 申し訳ございません 土日は忙しく返信を怠っておりました。 > 役に立った/立たなかったぐらいはすぐ返せるはず こちら仰る通りでございます。 以後気をつけます。 質問時に返信できる曜日等を記載するように致します
Zuishin

2021/09/27 02:35

「以後」じゃなく「この質問で」やれということですが。
EleAco

2021/09/27 02:37

Zuishinさん ただいま貼っていただいた記事を拝見し実際にコードを動かし検証中です
EleAco

2021/09/27 03:08

Zuishinさん 記事ありがとうございました。 拝見いたしました。 これをふまえ回答してくださった方の内容を見ていきます。
Zuishin

2021/09/27 04:02

> 変数countの中身は19でした。 同じコードを試してみましたが、13 になりました。 環境は以下の通りです。 .NET 5 C# 9.0 Visual Studio 2022 preview
EleAco

2021/09/27 04:03

Zuishinさん コードを試してくださりありがとうございます。 環境を質問に追記いたします。
退会済みユーザー

退会済みユーザー

2021/09/27 04:10

回答に、 > 以下の .NET 5.0 のコンソールアプリで、 と書きましたように、.NET 5.0 で試してみてください。
guest

回答2

0

ベストアンサー

以下の記事が参考になりませんか?

サロゲートペアや結合文字が含まれているか調べる
https://dobon.net/vb/dotnet/string/issurrogatepair.html

【追記】

上に紹介した記事からリンクが貼ってある以下の記事の通りやってみました。

文字列の長さ(文字数)を取得する
https://dobon.net/vb/dotnet/string/stringlength.html

以下の .NET 5.0 のコンソールアプリで、

イメージ説明

結果は以下の通りとなります。

イメージ説明

みた通りの14文字としてカウントしたいです。

自分には 13 文字に見えますけど。上の結果では「今日は家族で旅行に行った????‍????‍????‍????」は 13 文字になります。

投稿2021/09/24 21:28

編集2021/09/25 00:32
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

EleAco

2021/09/27 03:54

SurferOnWwwさん 回答ありがとうございます 同じように記述をしたのですがカウントは19でした。 エディタによって違うものなのでしょうか、、 質問に記述した内容を追記しておきます
退会済みユーザー

退会済みユーザー

2021/09/27 04:11

回答に、 > 以下の .NET 5.0 のコンソールアプリで、 と書きましたように、.NET 5.0 で試してみてください。
EleAco

2021/09/27 04:32

.NET 5.0 で動作確認したところカウントは13でした 無事解決いたしました。 ありがとうございました!????‍♂️
guest

0

諦めることを強くおすすめします。
「文字数」の定義が複雑かつ曖昧なので面倒なだけでどうせ見た目と合いませんし、合ったところで特にいいことはありません。

ただ一応、どうしてもというならTextElementEnumeratorなるものが比較的「文字数」に近い概念であるGrapheme Cluster(書記素クラスタ)の個数を扱えるようです。
StringInfo and TextElementEnumerator are now UAX29-compliant

「????‍????‍????‍????」の問題はサロゲートペアではなく(まあサロゲートペアも使われてはいますが)Emoji ZWJ Sequenceです。
Emoji ZWJ Sequenceは一応Grapheme Clusterではそれなりに「文字数」のようなものが数えられますが、フォントの対応いかんによって見た目の文字数は変わります。
更に言えばMicrosoftが自社のフォントでだけ1文字に見える職業猫絵文字を定義していたりします。
つまり見た目の文字数は環境依存です。

このGraphem Clusterを求めるアルゴリズムは「書記素分割/Unicode カテゴリー判定 | ++C++; // 未確認飛行 C ブログ」によれば

Unicode 標準としては、「あくまで参考。もっといいアルゴリズムにしてもらってもいいけど」という但し書き付きですが

というレベルのもので、これで完璧というようなものではありません。
(追記)
↑この部分、どの実装にも共通するGrapheme Clusterを求めるアルゴリズム自体(=Grapheme Clusterの定義)についてのものだと読んでいましたが、そうではなくUnicodeのドキュメントに書かれたある1つの実装のアルゴリズムに対してのものであり、私の主張とは無関係なものでした。取り消します。(コメント参照)
根拠がやや弱くなりますが、以下の主張に変更はありません。
(追記終)

そもそも世界の様々な文字を考えれば、「文字数」などまともに定義できるものではありません。
その一方でGraphem Clusterを求めるためにはUnicodeの全ての文字に対する巨大なテーブルを引いて文字ごとの属性を得る面倒な処理が必要です。Unicodeのバージョンが上がればテーブルは更新しなければなりません。

というわけで、労力に見合う意義がないのでやめた方がいいです。

投稿2021/09/24 22:58

編集2021/09/25 14:02
ikadzuchi

総合スコア3047

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

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

Zuishin

2021/09/24 23:22

> このGraphem Clusterを求めるアルゴリズムは 自作の実装の話です。それについてはこの回答で触れられていません。
退会済みユーザー

退会済みユーザー

2021/09/24 23:28

> 特にいいことはありません あなたにとってはそうかも知れませんが、質問者さんにとってどうでしょう?
ikadzuchi

2021/09/25 13:36 編集

> Zuishinさん すみませんがおっしゃっている意味がわかりません。 何が自作の実装の話なのですか? 「それについて」というのはその「自作の実装」の話という解釈でよろしいですか? > SurferOnWwwさん 私にとっての話をしたつもりはありません。質問者にとっていいことが無いだろうと言っているつもりです。
退会済みユーザー

退会済みユーザー

2021/09/25 07:36

×: SurferOnWww 〇: SurferOnWww さん どうしてあなたが「質問者にとっていいことが無い」と分かるのですか? それは質問者さんの環境とかやりたいことに関わる話で、他人が判断することではなく、質問者さんが判断することだと思いますが。
TN8001

2021/09/25 11:10

単に(14文字は数え間違いとして)13文字を取りたいならZuishinさん・SurferOnWwwさんのLengthInTextElementsでいいんでしょう。 (ややこしくなるので)絵文字だけに注目しますが、????‍????‍????‍????はブラウザで見ると1文字に見えます。 しかしVisualStudio上では4文字に見え、コンソールに至っては?が11文字に見えます(SurferOnWwwさんの回答より) もうこの時点で私は(ikadzuchiさん回答の冒頭・末尾と)同じ感想を持ちました(のでカウンター高評価しました) エディタでも作っているなら重要なんでしょうけど、(過去質問を見る限り)EleAcoさんがエディタ等を作っていそうには感じませんでした(まあ勝手な想像なわけですが^^;
退会済みユーザー

退会済みユーザー

2021/09/25 11:42 編集

前提が全く決まってないなら答えようがないですが、質問文にある絵文字が一文字で出力可能な環境というのは推測できるので、SurferOnWwwさんの回答でいいんじゃないですか?(ikadzuchiさんが悪い回答とも思いませんので低評価はしませんが) 質問者さんが、この処理を使って何をしたいのかが気になるところですけど。
Zuishin

2021/09/25 12:20 編集

表示する環境やフォントなどを制限し、仕様を決めれば諦めなくて済むはずなので、「諦めろ」という回答はいささか乱暴だと思います。数えたいというからには数えなければならない理由があるんでしょうし、そこまで労力が必要になるようなことをしたいようにも見えません。 私の最初のコメントの意図ですが、まず前提として > 「あくまで参考。もっといいアルゴリズムにしてもらってもいいけど」という但し書き付きですが、 の部分は次の個所を指していると思われます。 > As in other Unicode algorithms, these specifications provide a logical description of the processes: implementations can achieve the same results without using code or data that follows these rules step-by-step. In particular, many production-grade implementations will use a state-table approach. In that case, the performance does not depend on the complexity or number of rules. Rather, performance is only affected by the number of characters that may match after the boundary position in a rule that applies. 読んでいただければわかりますが、これはユニコード標準のアルゴリズムが不完全という意味合いではありません。 「以下のような手順で判定できるが、この手順通りにコーディングする必要はなく、最適化して実装すればパフォーマンス面が改善できる」という意味合いのことが書いてあります。 それに加えて、ufcpp さんの記事では、あくまで Microsoft による実装ではなく、自身による実装( https://github.com/ufcpp/GraphemeSplitter )にしか触れられていません。 Microsoft による実装がパフォーマンスを考慮した改善がなされていないなどどこにも書いていない、ましてや判定自身が不完全ということもどこにも書いていないにもかかわらず、ufcpp さんの記事にそう書いているように読める回答なので低評価しました。
ikadzuchi

2021/09/25 14:05 編集

> SurferOnWwwさん まず敬称忘れについては単純ミスです。申し訳ありませんでした。 他人が判断することではないとはいえ、おそらく本人も良いことはないと感じるだろうと推測することはできます。 まあ断定的な書き方をしたのはまずかったかもしれません。 > Zuishinさん > 次の個所を指していると思われます。 ありがとうございます。見つけられませんでした。 なるほど、区切り方のアルゴリズムに自体に対してではなく、それの実装についての言及だったんですね。これは意味を取り違えていました。 「それに加えて」以降について。実装によらない区切り方のアルゴリズムについての言及だと思ったための勘違いです。異論ありません。回答訂正しました。
EleAco

2021/09/27 03:16

ikazuchiさん 回答ありがとうございます。 確かに諦めてしまうのも手かなと考えております。 >そもそも世界の様々な文字を考えれば、「文字数」などまともに定義できるものではありません。 その一方でGraphem Clusterを求めるためにはUnicodeの全ての文字に対する巨大なテーブルを引いて文字ごとの属性を得る面倒な処理が必要です。Unicodeのバージョンが上がればテーブルは更新しなければなりません。 やはりそうなのですね…
Zuishin

2021/09/27 03:55

巨大なテーブルを自前で用意する必要はありません。 この発言は一連のコメントを見ればわかるように誤解に基づくものであり、いまだに修正できていないだけです。 それとやはり何の事情(プログラムの目的など)も知らず諦めろという結論が誤っているとしか思えないので、再度低評価します。
ikadzuchi

2021/10/02 21:15

> 巨大なテーブルを自前で用意する必要はありません。 > この発言は一連のコメントを見ればわかるように誤解に基づくものであり、いまだに修正できていないだけです。 「自前で」用意する必要があると言ったつもりはありません。どのような実装でも巨大なテーブルは必要だと考えています。そのテーブルを引くアルゴリズムには多々最適化が入るでしょうけれど。 > 何の事情(プログラムの目的など)も知らず諦めろという結論が誤っているとしか思えない そうですか。 私は質問者さんの反応を見る限り事情の推測はそう間違ってはいなかったように感じています。
Zuishin

2021/10/02 21:52 編集

> 「自前で」用意する必要があると言ったつもりはありません。どのような実装でも巨大なテーブルは必要だと考えています。そのテーブルを引くアルゴリズムには多々最適化が入るでしょうけれど。 ライブラリを使えば自分でテーブルを引かなくていいでしょう。 諦める理由の一つにはなりません。 > 私は質問者さんの反応を見る限り事情の推測はそう間違ってはいなかったように感じています。 意味不明です。SurferOnWww さんの回答で解決しています。
ikadzuchi

2021/10/17 16:02

> ライブラリを使えば自分でテーブルを引かなくていいでしょう。 > 諦める理由の一つにはなりません。 「『自前で』用意する必要があると言ったつもりはありません」と言ったつもりですが。 自前にせよライブラリにせよ巨大なテーブル引きという面倒な処理が行われること自体を問題視しています。 > 意味不明です。SurferOnWww さんの回答で解決しています。 他者の回答で解決したことがなぜ事情の推測の間違いの理由になると思っているのか理解できません。
Zuishin

2021/10/18 01:28

> 自前にせよライブラリにせよ巨大なテーブル引きという面倒な処理が行われること自体を問題視しています。 巨大なテーブル引きはライブラリの実装依存です。 テーブルを引かなくても計算で求められることは書いている通りです。 テーブルは高速化のためだけなので問題にはなりません。 テーブル自体も計算で作れます。 > 他者の回答で解決したことがなぜ事情の推測の間違いの理由になると思っているのか理解できません。 あなたの推測が正しければそれで解決していないからです。 なぜ理解できないのか理解できません。
ikadzuchi

2021/10/24 16:55

> 巨大なテーブル引きはライブラリの実装依存です。 最初は「"自前で"用意する必要はありません」「"自分で"テーブルを引かなくていいでしょう」と言っていたので巨大テーブルが必須なことには同意されていたものかと思っていたのですが…。 巨大テーブルが必要ないと言うなら最初から言ってほしかったですね。 > テーブルを引かなくても計算で求められることは書いている通りです。 どこに書いているのでしょう。そのようなことはあなたのコメント中に見つかりませんが。 もしかして 「many production-grade implementations will use a state-table approach」 の部分のことを言っていますか? 私の言っているテーブル引きは「Unicodeの全ての文字に対して文字の属性を引くためのテーブル」のことを言っているのですが。 > あなたの推測が正しければそれで解決していないからです。 文章の意味が分かりません。 「あなたの推測が正しければそれで解決しているはずであるが、していないから」と言いたいのでしょうか? > なぜ理解できないのか理解できません。 理解できないのはあなたに根本的に自分と異なる意見を理解しようとする気がないためでしょうね。 あと必要条件と十分条件あたりの論理の理解が不十分なのではないでしょうか。
Zuishin

2021/10/24 18:30

属性のテーブルは Unicode を使う限り、この処理に関係なく必ず必要になります。 何を言っているんですかあなたは? 理解が不十分なのではないでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問