Java에서 CamelCase를 사람이 읽을 수있는 이름으로 어떻게 변환합니까?
CamelCase를 사람이 읽을 수있는 이름으로 변환하는 메소드를 작성하고 싶습니다.
테스트 사례는 다음과 같습니다.
public void testSplitCamelCase() {
assertEquals("lowercase", splitCamelCase("lowercase"));
assertEquals("Class", splitCamelCase("Class"));
assertEquals("My Class", splitCamelCase("MyClass"));
assertEquals("HTML", splitCamelCase("HTML"));
assertEquals("PDF Loader", splitCamelCase("PDFLoader"));
assertEquals("A String", splitCamelCase("AString"));
assertEquals("Simple XML Parser", splitCamelCase("SimpleXMLParser"));
assertEquals("GL 11 Version", splitCamelCase("GL11Version"));
}
이것은 테스트 케이스와 함께 작동합니다.
static String splitCamelCase(String s) {
return s.replaceAll(
String.format("%s|%s|%s",
"(?<=[A-Z])(?=[A-Z][a-z])",
"(?<=[^A-Z])(?=[A-Z])",
"(?<=[A-Za-z])(?=[^A-Za-z])"
),
" "
);
}
테스트 하네스는 다음과 같습니다.
String[] tests = {
"lowercase", // [lowercase]
"Class", // [Class]
"MyClass", // [My Class]
"HTML", // [HTML]
"PDFLoader", // [PDF Loader]
"AString", // [A String]
"SimpleXMLParser", // [Simple XML Parser]
"GL11Version", // [GL 11 Version]
"99Bottles", // [99 Bottles]
"May5", // [May 5]
"BFG9000", // [BFG 9000]
};
for (String test : tests) {
System.out.println("[" + splitCamelCase(test) + "]");
}
공백을 삽입 할 위치를 찾기 위해 lookbehind 및 lookforward와 함께 길이가 일치하지 않는 정규 표현식을 사용합니다. 기본적으로 3 가지 패턴이 있으며 String.format
더 읽기 쉽게 만들기 위해 패턴 을 조합하는 데 사용합니다.
세 가지 패턴은 다음과 같습니다.
내 뒤의 UC, 내 뒤의 LC, 뒤의 LC
XMLParser AString PDFLoader
/\ /\ /\
내 뒤에 비 UC, 내 앞에 UC
MyClass 99Bottles
/\ /\
내 뒤에 편지, 내 앞에 편지가 아닌
GL11 May5 BFG9000
/\ /\ /\
참고 문헌
관련 질문
길이가 일치하지 않는 lookaround를 사용하여 분할 :
당신은 그것을 사용하여 그것을 할 수 있습니다 org.apache.commons.lang.StringUtils
StringUtils.join(
StringUtils.splitByCharacterTypeCamelCase("ExampleTest"),
' '
);
깔끔하고 짧은 해결책 :
StringUtils.capitalize(StringUtils.join(StringUtils.splitByCharacterTypeCamelCase("yourCamelCaseText"), StringUtils.SPACE)); // Your Camel Case Text
If you don't like "complicated" regex's, and aren't at all bothered about efficiency, then I've used this example to achieve the same effect in three stages.
String name =
camelName.replaceAll("([A-Z][a-z]+)", " $1") // Words beginning with UC
.replaceAll("([A-Z][A-Z]+)", " $1") // "Words" of only UC
.replaceAll("([^A-Za-z ]+)", " $1") // "Words" of non-letters
.trim();
It passes all the test cases above, including those with digits.
As I say, this isn't as good as using the one regular expression in some other examples here - but someone might well find it useful.
You can use org.modeshape.common.text.Inflector.
Specifically:
String humanize(String lowerCaseAndUnderscoredWords, String... removableTokens)
Capitalizes the first word and turns underscores into spaces and strips trailing "_id" and any supplied removable tokens.
Maven artifact is: org.modeshape:modeshape-common:2.3.0.Final
on JBoss repository: https://repository.jboss.org/nexus/content/repositories/releases
Here's the JAR file: https://repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar
The following Regex can be used to identify the capitals inside words:
"((?<=[a-z0-9])[A-Z]|(?<=[a-zA-Z])[0-9]]|(?<=[A-Z])[A-Z](?=[a-z]))"
It matches every capital letter, that is ether after a non-capital letter or digit or followed by a lower case letter and every digit after a letter.
How to insert a space before them is beyond my Java skills =)
Edited to include the digit case and the PDF Loader case.
I think you will have to iterate over the string and detect changes from lowercase to uppercase, uppercase to lowercase, alphabetic to numeric, numeric to alphabetic. On every change you detect insert a space with one exception though: on a change from upper- to lowercase you insert the space one character before.
This works in .NET... optimize to your liking. I added comments so you can understand what each piece is doing. (RegEx can be hard to understand)
public static string SplitCamelCase(string str)
{
str = Regex.Replace(str, @"([A-Z])([A-Z][a-z])", "$1 $2"); // Capital followed by capital AND a lowercase.
str = Regex.Replace(str, @"([a-z])([A-Z])", "$1 $2"); // Lowercase followed by a capital.
str = Regex.Replace(str, @"(\D)(\d)", "$1 $2"); //Letter followed by a number.
str = Regex.Replace(str, @"(\d)(\D)", "$1 $2"); // Number followed by letter.
return str;
}
For the record, here is an almost (*) compatible Scala version:
object Str { def unapplySeq(s: String): Option[Seq[Char]] = Some(s) }
def splitCamelCase(str: String) =
String.valueOf(
(str + "A" * 2) sliding (3) flatMap {
case Str(a, b, c) =>
(a.isUpper, b.isUpper, c.isUpper) match {
case (true, false, _) => " " + a
case (false, true, true) => a + " "
case _ => String.valueOf(a)
}
} toArray
).trim
Once compiled it can be used directly from Java if the corresponding scala-library.jar is in the classpath.
(*) it fails for the input "GL11Version"
for which it returns "G L11 Version"
.
I took the Regex from polygenelubricants and turned it into an extension method on objects:
/// <summary>
/// Turns a given object into a sentence by:
/// Converting the given object into a <see cref="string"/>.
/// Adding spaces before each capital letter except for the first letter of the string representation of the given object.
/// Makes the entire string lower case except for the first word and any acronyms.
/// </summary>
/// <param name="original">The object to turn into a proper sentence.</param>
/// <returns>A string representation of the original object that reads like a real sentence.</returns>
public static string ToProperSentence(this object original)
{
Regex addSpacesAtCapitalLettersRegEx = new Regex(@"(?<=[A-Z])(?=[A-Z][a-z]) | (?<=[^A-Z])(?=[A-Z]) | (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
string[] words = addSpacesAtCapitalLettersRegEx.Split(original.ToString());
if (words.Length > 1)
{
List<string> wordsList = new List<string> { words[0] };
wordsList.AddRange(words.Skip(1).Select(word => word.Equals(word.ToUpper()) ? word : word.ToLower()));
words = wordsList.ToArray();
}
return string.Join(" ", words);
}
This turns everything into a readable sentence. It does a ToString on the object passed. Then it uses the Regex given by polygenelubricants to split the string. Then it ToLowers each word except for the first word and any acronyms. Thought it might be useful for someone out there.
I'm not a regex ninja, so I'd iterate over the string, keeping the indexes of the current position being checked & the previous position. If the current position is a capital letter, I'd insert a space after the previous position and increment each index.
http://code.google.com/p/inflection-js/
You could chain the String.underscore().humanize() methods to take a CamelCase string and convert it into a human readable string.
'Programing' 카테고리의 다른 글
StoryBoard에서 탭 막대 컨트롤러 순서 재정렬 (0) | 2020.06.13 |
---|---|
WPF에서 하이퍼 링크를 사용하는 예 (0) | 2020.06.13 |
UIViewController 위에 clearColor UIViewController 표시 (0) | 2020.06.13 |
meld와 분기의 차이점을 보시겠습니까? (0) | 2020.06.13 |
jquery를 사용하여 여러 선택 상자 값을 얻는 방법은 무엇입니까? (0) | 2020.06.13 |