25

例えば:

thisIsMySample 

次のようにする必要があります。

this_Is_My_Sample

私のコード:

System.Text.RegularExpressions.Regex.Replace(input, "([A-Z])", "_$0", System.Text.RegularExpressions.RegexOptions.Compiled);

正常に動作しますが、入力が次のように変更された場合:

ThisIsMySample

出力は次のようになります。

_This_Is_My_Sample

最初の発生をどのように無視できますか?

4

7 に答える 7

44

非正規表現ソリューション

string result = string.Concat(input.Select((x,i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())); 

かなり速いようです: 正規表現: 2569ms、C#: 1489ms

Stopwatch stp = new Stopwatch();
stp.Start();
for (int i = 0; i < 1000000; i++)
{
    string input = "ThisIsMySample";
    string result = System.Text.RegularExpressions.Regex.Replace(input, "(?<=.)([A-Z])", "_$0",
            System.Text.RegularExpressions.RegexOptions.Compiled);
}
stp.Stop();
MessageBox.Show(stp.ElapsedMilliseconds.ToString());
// Result 2569ms

Stopwatch stp2 = new Stopwatch();
stp2.Start();
for (int i = 0; i < 1000000; i++)
{
    string input = "ThisIsMySample";
    string result = string.Concat(input.Select((x, j) => j > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString()));
}
stp2.Stop();
MessageBox.Show(stp2.ElapsedMilliseconds.ToString());
// Result: 1489ms
于 2013-09-13T08:19:33.890 に答える
15

後読みを使用して、各一致の前に少なくとも 1 つの文字があることを確認できます。

System.Text.RegularExpressions.Regex.Replace(input, "(?<=.)([A-Z])", "_$0",
                      System.Text.RegularExpressions.RegexOptions.Compiled);

先読みと後読みを使用すると、マッチ内にそのテキストを含めることなく、マッチを囲むテキストについてアサーションを行うことができます。

于 2013-09-13T07:57:58.627 に答える
4

たぶん好きです。

var str = Regex.Replace(input, "([A-Z])", "_$0", RegexOptions.Compiled);
if(str.StartsWith("_"))
   str = str.SubString(1);
于 2013-09-13T07:56:16.033 に答える
3
// (Preceded by a lowercase character or digit) (a capital) => The character prefixed with an underscore
var result = Regex.Replace(input, "(?<=[a-z0-9])[A-Z]", m => "_" + m.Value);
result = result.ToLowerInvariant();
  • これは と の両方PascalCaseで機能しcamelCaseます。
  • 先頭または末尾のアンダースコアは作成されません。
  • 文字列内の単語以外の文字とアンダースコアのシーケンスは、意図的に見えるため、そのまま残し__HiThere_Guysます__hi_there_guys
  • 数字のサフィックスは (意図的に) 単語の一部と見なされNewVersion3ますnew_version3
  • 数字の接頭辞は元の大文字小文字3VersionsHere3_versions_here従い3rdVersionます3rd_version
  • 残念ながら、Microsoft の Capitalization ConventionsIDNumberで提案されているように、大文字の 2 文字の頭字語 (たとえば、 in 、ID別の単語と見なされる場合) は、他のケースと競合するため、サポートされていません。一般に、頭字語を大文字にしないという慣習に対する一見恣意的な例外であるため、このガイドラインに抵抗することをお勧めします。固執します。IdNumber
于 2016-04-11T12:14:00.563 に答える
2

sa_ddam213 のソリューションを詳しく説明すると、私のものはこれを拡張します。

public static string GetConstStyleName(this string value)
        {
            return string.Concat(value.Select((x, i) =>
            {
                //want to avoid putting underscores between pairs of upper-cases or pairs of numbers, or adding redundant underscores if they already exist.
                bool isPrevCharLower = (i == 0) ? false : char.IsLower(value[i - 1]);
                bool isPrevCharNumber = (i == 0) ? false : char.IsNumber(value[i - 1]);
                return (isPrevCharLower && (char.IsUpper(x) || char.IsNumber(x))) //lower-case followed by upper-case or number needs underscore
                    || (isPrevCharNumber && (char.IsUpper(x))) //number followed by upper-case needs underscore
                    ? "_" + x.ToString() : x.ToString();
            })).ToUpperInvariant();
        }
于 2014-10-03T16:59:09.320 に答える
1

最初の文字をまったく無視するように定義して、最初の文字と一致しないように正規表現を変更する必要があります。

.([A-Z])

上記の正規表現は、最初に来るすべての文字を単純に除外します。それは中括弧に含まれていないため、一致するグループに含まれます。

ここで、Bibhu が指摘したように 2 番目のグループに一致させる必要があります。

System.Text.RegularExpressions.Regex.Replace(s, "(.)([A-Z])", "$1_$2", System.Text.RegularExpressions.RegexOptions.Compiled);
于 2013-09-13T07:56:15.683 に答える
1

".([A-Z])"正規表現に使用して"_$1"から、置換に使用します。したがって、キャプチャされた文字列を置換に使用し、リーディングを使用すると、.文字列の最初の文字をキャッチしていないと確信できます。

于 2013-09-13T07:57:29.323 に答える