program story

Pascal Case를 문장으로 변환하는 가장 좋은 방법

inputbox 2020. 11. 1. 17:42
반응형

Pascal Case를 문장으로 변환하는 가장 좋은 방법


Pascal Case (upper Camel Case)에서 문장으로 변환하는 가장 좋은 방법은 무엇입니까?

예를 들어

"AwaitingFeedback"

그리고 그것을

"Awaiting feedback"

C #이 바람직하지만 Java 또는 이와 유사한 것으로 변환 할 수 있습니다.


public static string ToSentenceCase(this string str)
{
    return Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1]));
}

2015 년 이후 Visual Studio 버전에서는 다음을 수행 할 수 있습니다.

public static string ToSentenceCase(this string str)
{
    return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}");
}

기반 : 정규 표현식을 사용하여 Pascal 대소 문자를 문장으로 변환


여기 있습니다 ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CamelCaseToString
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(CamelCaseToString("ThisIsYourMasterCallingYou"));   
        }

        private static string CamelCaseToString(string str)
        {
            if (str == null || str.Length == 0)
                return null;

            StringBuilder retVal = new StringBuilder(32);

            retVal.Append(char.ToUpper(str[0]));
            for (int i = 1; i < str.Length; i++ )
            {
                if (char.IsLower(str[i]))
                {
                    retVal.Append(str[i]);
                }
                else
                {
                    retVal.Append(" ");
                    retVal.Append(char.ToLower(str[i]));
                }
            }

            return retVal.ToString();
        }
    }
}

이것은 나를 위해 작동합니다.

Regex.Replace(strIn, "([A-Z]{1,2}|[0-9]+)", " $1").TrimStart()

나는 이것을 위해 Humanizer 를 사용하는 것을 선호합니다 . Humanizer는 문자열, 열거 형, 날짜, 시간, 시간 범위, 숫자 및 수량을 조작하고 표시하는 데 필요한 모든 .NET 요구 사항을 충족하는 이식 가능한 클래스 라이브러리입니다.

짧은 답변

"AwaitingFeedback".Humanize() => Awaiting feedback

길고 설명적인 답변

Humanizer는 더 많은 작업을 수행 할 수 있습니다. 다른 예는 다음과 같습니다.

"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence"
"Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence"
"Can_return_title_Case".Humanize(LetterCasing.Title) => "Can Return Title Case"
"CanReturnLowerCase".Humanize(LetterCasing.LowerCase) => "can return lower case"

완전한 코드는 다음과 같습니다.

using Humanizer;
using static System.Console;

namespace HumanizerConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine("AwaitingFeedback".Humanize());
            WriteLine("PascalCaseInputStringIsTurnedIntoSentence".Humanize());
            WriteLine("Underscored_input_string_is_turned_into_sentence".Humanize());
            WriteLine("Can_return_title_Case".Humanize(LetterCasing.Title));
            WriteLine("CanReturnLowerCase".Humanize(LetterCasing.LowerCase));
        }
    }
}

산출

피드백을 기다리고

파스칼 케이스 입력 문자열이 문장으로 바뀝니다.

밑줄이 표시된 입력 문자열이 문장으로 바뀝니다.

소문자 반환 가능

자신 만의 C # 코드를 작성하고 싶다면 이미 다른 사람들이 대답 한대로 C # 코드를 작성하여이를 달성 할 수 있습니다.


이것은 @SSTA와 비슷하지만 TrimStart를 호출하는 것보다 더 효율적입니다.

Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1")

MvcContrib 소스에서 이것을 찾았지만 아직 여기에 언급되지 않은 것 같습니다.

return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim();

Regex를 사용하여 생각 해낸 기본적인 방법은 다음과 같습니다.

public static string CamelCaseToSentence(this string value)
{
    var sb = new StringBuilder();
    var firstWord = true;

    foreach (var match in Regex.Matches(value, "([A-Z][a-z]+)|[0-9]+"))
    {
        if (firstWord)
        {
            sb.Append(match.ToString());
            firstWord = false;
        }
        else
        {
            sb.Append(" ");
            sb.Append(match.ToString().ToLower());
        }
    }

    return sb.ToString();
}

또한 지정하지 않았지만 유용 할 수있는 숫자를 분리합니다.


정규식을 사용하여 각 대문자 앞에 공백을 삽입 한 다음 모든 문자열을 낮 춥니 다.

    string spacedString = System.Text.RegularExpressions.Regex.Replace(yourString, "\B([A-Z])", " \k");
    spacedString = spacedString.ToLower();

string camel = "MyCamelCaseString";
string s = Regex.Replace(camel, "([A-Z])", " $1").ToLower().Trim();
Console.WriteLine(s.Substring(0,1).ToUpper() + s.Substring(1));

편집 : 그에 따라 수정 된 대 / 소문자 요구 사항을 알아 차리지 못했습니다. 대 / 소문자를 구분하기 위해 matchevaluator를 사용할 수 있지만 하위 문자열이 더 쉽다고 생각합니다. 첫 번째 문자를 변경하는 위치를 두 번째 정규식으로 래핑 할 수도 있습니다.

"^\w"

상단으로

\U (i think)

replace 호출에서 함수를 정의 할 수있는 JavaScript (또는 PHP 등)에서 쉽게 수행 할 수 있습니다.

var camel = "AwaitingFeedbackDearMaster";
var sentence = camel.replace(/([A-Z].)/g, function (c) { return ' ' + c.toLowerCase(); });
alert(sentence);

초기 모자 문제를 해결하지 못했지만 ... :-)

이제 Java 솔루션의 경우 :

String ToSentence(String camel)
{
  if (camel == null) return ""; // Or null...
  String[] words = camel.split("(?=[A-Z])");
  if (words == null) return "";
  if (words.length == 1) return words[0];
  StringBuilder sentence = new StringBuilder(camel.length());
  if (words[0].length() > 0) // Just in case of camelCase instead of CamelCase
  {
    sentence.append(words[0] + " " + words[1].toLowerCase());
  }
  else
  {
    sentence.append(words[1]);
  }
  for (int i = 2; i < words.length; i++)
  {
    sentence.append(" " + words[i].toLowerCase());
  }
  return sentence.toString();
}

System.out.println(ToSentence("AwaitingAFeedbackDearMaster"));
System.out.println(ToSentence(null));
System.out.println(ToSentence(""));
System.out.println(ToSentence("A"));
System.out.println(ToSentence("Aaagh!"));
System.out.println(ToSentence("stackoverflow"));
System.out.println(ToSentence("disableGPS"));
System.out.println(ToSentence("Ahh89Boo"));
System.out.println(ToSentence("ABC"));

문자를 잃지 않고 문장을 분할하는 트릭에 유의하십시오.


모두가 Regex를 사용했기 때문에 ( 이 사람 제외 ) 여기 에 내 테스트에서 StringBuilder5 배 더 빠른 구현이 있습니다. 숫자 확인도 포함됩니다.

"SomeBunchOfCamelCase2".FromCamelCaseToSentence == "Some Bunch Of Camel Case 2"

public static string FromCamelCaseToSentence(this string input) {
    if(string.IsNullOrEmpty(input)) return input;

    var sb = new StringBuilder();
    // start with the first character -- consistent camelcase and pascal case
    sb.Append(char.ToUpper(input[0]));

    // march through the rest of it
    for(var i = 1; i < input.Length; i++) {
        // any time we hit an uppercase OR number, it's a new word
        if(char.IsUpper(input[i]) || char.IsDigit(input[i])) sb.Append(' ');
        // add regularly
        sb.Append(input[i]);
    }

    return sb.ToString();
}

의사 코드 :

NewString = "";
Loop through every char of the string (skip the first one)
   If char is upper-case ('A'-'Z')
     NewString = NewString + ' ' + lowercase(char)
   Else
     NewString = NewString + char

더 나은 방법은 정규식을 사용하거나 문자열 대체 루틴을 사용하여 수행 할 수 있습니다 ( 'X'를 'x'로 대체).


UpperCamel 및 lowerCamel 케이스 모두에서 작동하는 xquery 솔루션 :

문장 대소 문자를 출력하려면 (첫 번째 단어의 첫 문자 만 대문자로 표시됨) :

declare function content:sentenceCase($string)
{
let $firstCharacter := substring($string, 1, 1)
let $remainingCharacters := substring-after($string, $firstCharacter)
return
concat(upper-case($firstCharacter),lower-case(replace($remainingCharacters, '([A-Z])', ' $1')))
};

제목 대소 문자를 출력하려면 (각 단어의 첫 문자를 대문자로 표시) :

declare function content:titleCase($string)
{
let $firstCharacter := substring($string, 1, 1)
let $remainingCharacters := substring-after($string, $firstCharacter)
return
concat(upper-case($firstCharacter),replace($remainingCharacters, '([A-Z])', ' $1'))
};

나 자신이 비슷한 일을하고 있다는 것을 알게되었고,이 토론과 함께 출발 지점을 갖는 것에 감사드립니다. 이것은 콘솔 응용 프로그램의 컨텍스트에서 문자열 클래스에 대한 확장 메서드로 배치 된 내 솔루션입니다.

using System;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string piratese = "avastTharMatey";
            string ivyese = "CheerioPipPip";

            Console.WriteLine("{0}\n{1}\n", piratese.CamelCaseToString(), ivyese.CamelCaseToString());
            Console.WriteLine("For Pete\'s sake, man, hit ENTER!");
            string strExit = Console.ReadLine();
        }

    }

    public static class StringExtension
    {
        public static string CamelCaseToString(this string str)
        {
            StringBuilder retVal = new StringBuilder(32);

            if (!string.IsNullOrEmpty(str))
            {
                string strTrimmed = str.Trim();

                if (!string.IsNullOrEmpty(strTrimmed))
                {
                    retVal.Append(char.ToUpper(strTrimmed[0]));

                    if (strTrimmed.Length > 1)
                    {
                        for (int i = 1; i < strTrimmed.Length; i++)
                        {
                            if (char.IsUpper(strTrimmed[i])) retVal.Append(" ");

                            retVal.Append(char.ToLower(strTrimmed[i]));
                        }
                    }
                }
            }
            return retVal.ToString();
        }
    }
}

대부분 이미 여기에 답변

두 번째 및 후속 대문자를 소문자로 변환하려면 허용되는 대답에 작은 차이가 있으므로 변경하십시오.

if (char.IsUpper(text[i]))                
    newText.Append(' ');            
newText.Append(text[i]);

...에

if (char.IsUpper(text[i]))                
{
    newText.Append(' ');            
    newText.Append(char.ToLower(text[i]));
}
else
   newText.Append(text[i]);

앞의 답변 대부분은 약어와 숫자를 분리하여 각 문자 앞에 공백을 추가합니다. 나는 두문자어와 숫자가 함께 유지되기를 원했기 때문에 입력이 한 상태에서 다른 상태로 전환 될 때마다 공백을 방출하는 간단한 상태 머신이 있습니다.

    /// <summary>
    /// Add a space before any capitalized letter (but not for a run of capitals or numbers)
    /// </summary>
    internal static string FromCamelCaseToSentence(string input)
    {
        if (string.IsNullOrEmpty(input)) return String.Empty;

        var sb = new StringBuilder();
        bool upper = true;

        for (var i = 0; i < input.Length; i++)
        {
            bool isUpperOrDigit = char.IsUpper(input[i]) || char.IsDigit(input[i]);
            // any time we transition to upper or digits, it's a new word
            if (!upper && isUpperOrDigit)
            {
                sb.Append(' ');
            }
            sb.Append(input[i]);
            upper = isUpperOrDigit;
        }

        return sb.ToString();
    }

다음은 몇 가지 테스트입니다.

    [TestCase(null, ExpectedResult = "")]
    [TestCase("", ExpectedResult = "")]
    [TestCase("ABC", ExpectedResult = "ABC")]
    [TestCase("abc", ExpectedResult = "abc")]
    [TestCase("camelCase", ExpectedResult = "camel Case")]
    [TestCase("PascalCase", ExpectedResult = "Pascal Case")]
    [TestCase("Pascal123", ExpectedResult = "Pascal 123")]
    [TestCase("CustomerID", ExpectedResult = "Customer ID")]
    [TestCase("CustomABC123", ExpectedResult = "Custom ABC123")]
    public string CanSplitCamelCase(string input)
    {
        return FromCamelCaseToSentence(input);
    }

참고 URL : https://stackoverflow.com/questions/323314/best-way-to-convert-pascal-case-to-a-sentence

반응형