如何将CamelCase转换为Java中的可读名称?
我想写一个方法,将CamelCase转换成人类可读的名字。
这里是testing用例:
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")); }
这适用于您的testing用例:
static String splitCamelCase(String s) { return s.replaceAll( String.format("%s|%s|%s", "(?<=[AZ])(?=[AZ][az])", "(?<=[^AZ])(?=[AZ])", "(?<=[A-Za-z])(?=[^A-Za-z])" ), " " ); }
这是一个testing工具:
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) + "]"); }
它使用零长度匹配的正则expression式与lookbehind和lookforwardfind哪里插入空格。 基本上有3个模式,我使用String.format
将它们放在一起,使其更具可读性。
这三种模式是:
在我身后的UC,UC跟着LC在我面前
XMLParser AString PDFLoader /\ /\ /\
在我之前没有UC,UC在我面前
MyClass 99Bottles /\ /\
在我背后的信,在我面前的非信
GL11 May5 BFG9000 /\ /\ /\
参考
- regular-expressions.info/Lookarounds
相关问题
使用零长度匹配查找来分割:
- 正则expression式拆分string,但保留分隔符
- Java分裂正在吃我的angular色
你可以使用org.apache.commons.lang.StringUtils
StringUtils.join( StringUtils.splitByCharacterTypeCamelCase("ExampleTest"), ' ' );
如果你不喜欢“复杂”的正则expression式,并且一点都不关心效率,那么我就用这个例子来分三个阶段达到同样的效果。
String name = camelName.replaceAll("([AZ][az]+)", " $1") // Words beginning with UC .replaceAll("([AZ][AZ]+)", " $1") // "Words" of only UC .replaceAll("([^A-Za-z ]+)", " $1") // "Words" of non-letters .trim();
它通过了上面所有的testing用例,包括带有数字的testing用例。
正如我所说,这不如在这里的其他例子中使用一个正则expression式 – 但有人可能会发现它有用。
你可以使用org.modeshape.common.text.Inflector 。
特别:
String humanize(String lowerCaseAndUnderscoredWords, String... removableTokens)
大写第一个单词,并将下划线转换为空格和带“_id”和任何提供的可移动令牌。
Maven神器是: org.modeshape:modeshape-common:2.3.0.Final
在JBoss仓库上: https : //repository.jboss.org/nexus/content/repositories/releases
这里是JAR文件: https : //repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar
下面的正则expression式可以用来标识单词中的大写字母:
"((?<=[a-z0-9])[AZ]|(?<=[a-zA-Z])[0-9]]|(?<=[AZ])[AZ](?=[az]))"
它匹配每个大写字母,即非大写字母或数字之后的乙醚,或者后面跟着一个小写字母和一个字母后的每个数字。
如何在他们之前插入一个空间超出了我的Java技能=)
编辑包括数字大小写和PDF加载器的情况。
我想你将不得不遍历string,并检测从小写到大写,大写到小写,字母到数字,数字到字母的变化。 在检测到的每一个变化中,除了一个例外之外,插入一个空格:在从大写字母到小写字母的变化中,插入一个字符之前的空格。
这在.NET中工作…优化你的喜好。 我添加了评论,所以你可以理解每件作品在做什么。 (RegEx可能很难理解)
public static string SplitCamelCase(string str) { str = Regex.Replace(str, @"([AZ])([AZ][az])", "$1 $2"); // Capital followed by capital AND a lowercase. str = Regex.Replace(str, @"([az])([AZ])", "$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; }
我不是一个正则expression式忍者,所以我会遍历string,保持当前位置的索引被检查和以前的位置。 如果当前位置是一个大写字母,我会在前一个位置后面插入一个空格,并增加每个索引。
为了logging,这是一个几乎(*)兼容的Scala版本:
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
编译完成后,如果相应的scala-library.jar位于类path中,则可以直接从Java中使用它。
(*)input的"GL11Version"
失败,返回"G L11 Version"
。
我从polygenelubricants采取正则expression式并且变成对象的扩展方法:
/// <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(@"(?<=[AZ])(?=[AZ][az]) | (?<=[^AZ])(?=[AZ]) | (?<=[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); }
这将一切变成一个可读的句子。 它在传递的对象上做了一个ToString。 然后它使用由polygenelubricants给出的正则expression式来分割string。 然后它除了第一个单词和任何缩略词外, 认为这可能对那里的人有用。
整洁而简短的解决scheme:
StringUtils.capitalize(StringUtils.join(StringUtils.splitByCharacterTypeCamelCase("yourCamelCaseText"), StringUtils.SPACE)); // Your Camel Case Text
RegEx应该工作,像([AZ]{1})
。 这将捕获所有大写字母,之后,您可以用\1
replace它们,或者您可以如何引用Java中的正则expression式组。
http://code.google.com/p/inflection-js/
你可以链接String.underscore()。humanize()方法来获取一个CamelCasestring并将其转换为一个可读的string。