将camelCaseText转换成句子大小写文本


144

如何在JavaScript中将字符串“ helloThere”或“ HelloThere”转换为“ Hello There”?


9
嗯.. iLiveInTheUSA的预期输出是什么?
2011年

8
我住在U ...哦,废话!-但就我而言,我的字符串集有限,没有这样的字符串会破坏简单的转换器。好收成!
HyderA 2011年

同样,uSBPort应该产生“ USB端口”
signonsridhar

2
@wim:iLiveInTheUSA应该是正确的驼峰大小写形式的iLiveInTheUsa,但这会带来不同的问题。
KonradHöffner,

Answers:


186
var text = 'helloThereMister';
var result = text.replace( /([A-Z])/g, " $1" );
var finalResult = result.charAt(0).toUpperCase() + result.slice(1);
console.log(finalResult);

以首字母大写为例。

注意中的空格" $1"

编辑:添加了首个字母大写的示例。当然,如果第一个字母已经是大写字母-您将有一个备用空间来删除​​。


1
我在中挖掘了空格的使用text.replace,我也一直在为函数调用填充2个以上带有空格的参数以提高可读性
rkd

8
uSBPorts => USB端口,不是我所期望的,我想要一个USB端口
signonsridhar

像这样写Non-GoogleChrome呢?
蒂姆

107

或者使用lodash

lodash.startCase(str);

例:

_.startCase('helloThere');
// ➜ 'Hello There'

Lodash是一个很好的图书馆给快捷方式到许多日常JS tasks.There是许多其他类似的字符串处理函数,例如camelCasekebabCase等等。


如果您尝试这样做,hello world则输出应为Hello There,在这种情况下,loadash将无济于事。
Abhishek Kumar

lodash的@AbhishekKumar startCase实际上将转换hello worldHello World lodash.com/docs/4.17.15#upperFirst
user1696017

你是对的兄弟。我写错hello therehello world
Abhishek Kumar

2
每当我认为“ Lodash也绝不可能做到”时,它也会这样做。
efru

从v4开始,请小心,此函数删除ä等特殊字符并将其转换为ASCII(在这种情况下为a)
collerek

52

我有一个类似的问题,并这样处理:

stringValue.replace(/([A-Z]+)*([A-Z][a-z])/g, "$1 $2")

对于更强大的解决方案:

stringValue.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1")

http://jsfiddle.net/PeYYQ/

输入:

 helloThere 
 HelloThere 
 ILoveTheUSA
 iLoveTheUSA

输出:

 hello There 
 Hello There 
 I Love The USA
 i Love The USA

它为开始增加了空间
Hannad Rehman

4
这不是OP要求的判刑案例。首字母应大写。
H Dog

此外,它在单词之间增加了一个额外的空间
Alacritas

34

没有副作用的例子。

function camel2title(camelCase) {
  // no side-effects
  return camelCase
    // inject space before the upper case letters
    .replace(/([A-Z])/g, function(match) {
       return " " + match;
    })
    // replace first char with upper case
    .replace(/^./, function(match) {
      return match.toUpperCase();
    });
}

在ES6中

const camel2title = (camelCase) => camelCase
  .replace(/([A-Z])/g, (match) => ` ${match}`)
  .replace(/^./, (match) => match.toUpperCase());

1
稳定,es6代码段为+1。
BradStell

4
仅供参考,这会在句子的开头添加额外的空格。
Dale Zak

20

我找到的用于测试驼峰大小写到标题大小写功能的最佳字符串是这个荒谬的,毫无意义的示例,它测试了许多边缘情况。据我所知,以前发布的函数均无法正确处理此问题

马上获得有关GED的基本信息,但对于用户456在房间26A中包含个人ID卡,包含ABC26的时间就不那么容易了,因为C3POOrR2D2Or2R2D

这应该转换为:

及时获取GED的本质是一首关于26 ABC的歌曲,但是在房间26A中包含ABC 26次的用户456的个人ID卡并不像C3PO或R2D2或2R2D的123那样容易

如果您只需要一个简单的函数来处理上述情况(比以前的答案要多的情况),这就是我写的一个。这段代码并不是特别优雅或快速,但是它简单,易于理解并且可以正常工作。

一个在线可运行示例在jsfiddle上,或者您可以在控制台中查看以下代码段的输出:

// Take a single camel case string and convert it to a string of separate words (with spaces) at the camel-case boundaries.
// 
// E.g.:
var examples = [
    'ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D',
    //                                          --> To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D
    'helloThere', //                              --> Hello There
    'HelloThere', //                              --> Hello There
    'ILoveTheUSA', //                             --> I Love The USA
    'iLoveTheUSA', //                             --> I Love The USA
    'DBHostCountry', //                           --> DB Host Country
    'SetSlot123ToInput456', //                    --> Set Slot 123 To Input 456
    'ILoveTheUSANetworkInTheUSA', //              --> I Love The USA Network In The USA
    'Limit_IOC_Duration', //                      --> Limit IOC Duration
    'This_is_a_Test_of_Network123_in_12_days', // --> This Is A Test Of Network 123 In 12 Days
    'ASongAboutTheABCsIsFunToSing', //            --> A Song About The ABCs Is Fun To Sing
    'CFDs', //                                    --> CFDs
    'DBSettings', //                              --> DB Settings
    'IWouldLove1Apple', //                        --> 1 Would Love 1 Apple
    'Employee22IsCool', //                        --> Employee 22 Is Cool
    'SubIDIn', //                                 --> Sub ID In
    'ConfigureCFDsImmediately', //                --> Configure CFDs Immediately
    'UseTakerLoginForOnBehalfOfSubIDInOrders', // --> Use Taker Login For On Behalf Of Sub ID In Orders
]

function camelCaseToTitleCase(in_camelCaseString) {
        var result = in_camelCaseString                         // "ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D"
            .replace(/([a-z])([A-Z][a-z])/g, "$1 $2")           // "To Get YourGEDIn TimeASong About The26ABCs IsOf The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times IsNot AsEasy As123ForC3POOrR2D2Or2R2D"
            .replace(/([A-Z][a-z])([A-Z])/g, "$1 $2")           // "To Get YourGEDIn TimeASong About The26ABCs Is Of The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2")          // "To Get Your GEDIn Time ASong About The26ABCs Is Of The Essence But APersonal IDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2")     // "To Get Your GEDIn Time A Song About The26ABCs Is Of The Essence But A Personal ID Card For User456In Room26A ContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2")           // "To Get Your GEDIn Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3POOr R2D2Or 2R2D"
            
            // Note: the next regex includes a special case to exclude plurals of acronyms, e.g. "ABCs"
            .replace(/([A-Z]+)([A-Z][a-rt-z][a-z]*)/g, "$1 $2") // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"
            .replace(/([0-9])([A-Z][a-z]+)/g, "$1 $2")          // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC 26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"  

            // Note: the next two regexes use {2,} instead of + to add space on phrases like Room26A and 26ABCs but not on phrases like R2D2 and C3PO"
            .replace(/([A-Z]{2,})([0-9]{2,})/g, "$1 $2")        // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .replace(/([0-9]{2,})([A-Z]{2,})/g, "$1 $2")        // "To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .trim();


  // capitalize the first letter
  return result.charAt(0).toUpperCase() + result.slice(1);
}

examples.forEach(str => console.log(str, ' --> \n', camelCaseToTitleCase(str)));



10

好的,我迟到了几年,但是我有一个类似的问题,我想为每一个可能的输入提供一个替代解决方案。我必须给大部分的功劳要@ZenMaster该线程和@Benjamin Udink十大美食在这个线程。这是代码:

var camelEdges = /([A-Z](?=[A-Z][a-z])|[^A-Z](?=[A-Z])|[a-zA-Z](?=[^a-zA-Z]))/g;
var textArray = ["lowercase",
                 "Class",
                 "MyClass",
                 "HTML",
                 "PDFLoader",
                 "AString",
                 "SimpleXMLParser",
                 "GL11Version",
                 "99Bottles",
                 "May5",
                 "BFG9000"];
var text;
var resultArray = [];
for (var i = 0; i < a.length; i++){
    text = a[i];
    text = text.replace(camelEdges,'$1 ');
    text = text.charAt(0).toUpperCase() + text.slice(1);
    resultArray.push(text);
}

它具有三个子句,所有子句都使用前瞻性来防止正则表达式引擎占用太多字符:

  1. [A-Z](?=[A-Z][a-z])查找大写字母,后跟一个大写字母然后是一个小写字母。这是结束像美国这样的缩写词。
  2. [^A-Z](?=[A-Z])寻找一个非大写字母,后跟一个大写字母。这样就结束了诸如myWord之类的单词和诸如99Bottles之类的符号。
  3. [a-zA-Z](?=[^a-zA-Z])寻找字母,后跟非字母。这会在BFG9000之类的符号之前结束单词。

这个问题位于我搜索结果的顶部,因此希望我可以节省一些时间!


9

这是我的版本。它在每个小写英文字母之后的每个大写英文字母之前添加一个空格,并在需要时将首字母大写:

例如:
thisIsCamelCase->这是骆驼案例
this IsCamelCase->这是骆驼案例
thisIsCamelCase123- >这是骆驼案例 123

  function camelCaseToTitleCase(camelCase){
    if (camelCase == null || camelCase == "") {
      return camelCase;
    }

    camelCase = camelCase.trim();
    var newText = "";
    for (var i = 0; i < camelCase.length; i++) {
      if (/[A-Z]/.test(camelCase[i])
          && i != 0
          && /[a-z]/.test(camelCase[i-1])) {
        newText += " ";
      }
      if (i == 0 && /[a-z]/.test(camelCase[i]))
      {
        newText += camelCase[i].toUpperCase();
      } else {
        newText += camelCase[i];
      }
    }

    return newText;
  }

6

此实现考虑连续的大写字母和数字。

function camelToTitleCase(str) {
  return str
    .replace(/[0-9]{2,}/g, match => ` ${match} `)
    .replace(/[^A-Z0-9][A-Z]/g, match => `${match[0]} ${match[1]}`)
    .replace(/[A-Z][A-Z][^A-Z0-9]/g, match => `${match[0]} ${match[1]}${match[2]}`)
    .replace(/[ ]{2,}/g, match => ' ')
    .replace(/\s./g, match => match.toUpperCase())
    .replace(/^./, match => match.toUpperCase())
    .trim();
}

// ----------------------------------------------------- //

var testSet = [
    'camelCase',
    'camelTOPCase',
    'aP2PConnection',
    'superSimpleExample',
    'aGoodIPAddress',
    'goodNumber90text',
    'bad132Number90text',
];

testSet.forEach(function(item) {
    console.log(item, '->', camelToTitleCase(item));
});

预期产量:

camelCase -> Camel Case
camelTOPCase -> Camel TOP Case
aP2PConnection -> A P2P Connection
superSimpleExample -> Super Simple Example
aGoodIPAddress -> A Good IP Address
goodNumber90text -> Good Number 90 Text
bad132Number90text -> Bad 132 Number 90 Text

我会用克里斯·克莱恩(Chris Kline)的答案来容纳诸如“ IP地址”之类的字符串(其中此功能将其转换为“ IP地址”
John Hamm

@JohnHamm您输入的是“ IP地址”,对吗?这不是骆驼案!在此处阅读有关驼峰式保护套的信息:en.wikipedia.org/wiki/Camel_case 不要在两者之间加空格,而只能输入“ IPAddress”。此功能工作正常。
Dipu

3

您可以使用如下功能:

function fixStr(str) {
    var out = str.replace(/^\s*/, "");  // strip leading spaces
    out = out.replace(/^[a-z]|[^\s][A-Z]/g, function(str, offset) {
        if (offset == 0) {
            return(str.toUpperCase());
        } else {
            return(str.substr(0,1) + " " + str.substr(1).toUpperCase());
        }
    });
    return(out);
}

"hello World" ==> "Hello World"
"HelloWorld" ==> "Hello World"
"FunInTheSun" ==? "Fun In The Sun"

此处带有一串测试字符串的代码:http : //jsfiddle.net/jfriend00/FWLuV/

在此处保留前导空格的备用版本:http : //jsfiddle.net/jfriend00/Uy2ac/


我知道这不是问题的要求,但是您的解决方案不适" helloWorld"用于例如。
ZenMaster

是的,这是一个新要求。我试图完全按照您最初的要求进行。无论如何,如果您根本不需要引导空间,则捷径很容易划定。如果您希望它们保留在原位,也可以这样做。
jfriend00 2011年

这是一个jsFiddle,它显示了一种与新要求“ helloWorld”一起使用并保留前导空间(如果需要)的方法:jsfiddle.net/jfriend00/Uy2ac
jfriend00 2011年

真好 我不知道它的性能。每次比赛都会调用处理程序函数,不是吗?
ZenMaster

如果要在对性能敏感的环境中进行大量的工作,则需要在许多浏览器中进行一些jsperf测试,以了解最快的解决方案是什么。调用回调没什么大不了的。与专用代码相比,任何形式的正则表达式都很少是最快的解决方案,但是它们可以节省大量代码(通常还包括一些错误),因此通常是理想的选择。这取决于您的要求。
jfriend00

3

试试这个图书馆

http://sugarjs.com/api/String/titleize

'man from the boondocks'.titleize()>"Man from the Boondocks"
'x-men: the last stand'.titleize()>"X Men: The Last Stand"
'TheManWithoutAPast'.titleize()>"The Man Without a Past"
'raiders_of_the_lost_ark'.titleize()>"Raiders of the Lost Ark"

2

上面的答案都不适合我,因此必须自备自行车:

function camelCaseToTitle(camelCase) {
    if (!camelCase) {
        return '';
    }

    var pascalCase = camelCase.charAt(0).toUpperCase() + camelCase.substr(1);
    return pascalCase
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
        .replace(/([a-z])([0-9])/gi, '$1 $2')
        .replace(/([0-9])([a-z])/gi, '$1 $2');
}

测试用例:

null => ''
'' => ''
'simpleString' => 'Simple String'
'stringWithABBREVIATIONInside => 'String With ABBREVIATION Inside'
'stringWithNumber123' => 'String With Number 123'
'complexExampleWith123ABBR890Etc' => 'Complex Example With 123 ABBR 890 Etc'

2

这对我有用

CamelcaseToWord(“ MyName”); //返回我的名字

    function CamelcaseToWord(string){
      return string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1");
    }

1
欢迎使用SO :)请在您的代码中至少添加一条说明行。还要确保这是您的智力工作或引用来源。
罗伦兹·

您应该删除latt“ $ 1”中的空间。string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, "$1");
瓦莱里亚·史宾纳


2

如果您处理的是Capital Camel Case,此代码段可以为您提供帮助,并且其中包含一些规格,因此您可以确定它与您的情况相匹配。

export const fromCamelCaseToSentence = (word) =>
  word
    .replace(/([A-Z][a-z]+)/g, ' $1')
    .replace(/([A-Z]{2,})/g, ' $1')
    .replace(/\s{2,}/g, ' ')
    .trim();

和规格:

describe('fromCamelCaseToSentence', () => {
 test('does not fall with a single word', () => {
   expect(fromCamelCaseToSentence('Approved')).toContain('Approved')
   expect(fromCamelCaseToSentence('MDA')).toContain('MDA')
 })

 test('does not fall with an empty string', () => {
   expect(fromCamelCaseToSentence('')).toContain('')
 })

 test('returns the separated by space words', () => {
   expect(fromCamelCaseToSentence('NotApprovedStatus')).toContain('Not Approved Status')
   expect(fromCamelCaseToSentence('GDBState')).toContain('GDB State')
   expect(fromCamelCaseToSentence('StatusDGG')).toContain('Status DGG')
 })
})

1

我没有尝试每个人的答案,但是我尝试过的一些解决方案并不符合我的所有要求。

我想出了一些能做到的...

export const jsObjToCSSString = (o={}) =>
    Object.keys(o)
          .map(key => ({ key, value: o[key] }))
          .map(({key, value}) =>
              ({
                key: key.replace( /([A-Z])/g, "-$1").toLowerCase(),
                value
              })
          )
          .reduce(
              (css, {key, value}) => 
                  `${css} ${key}: ${value}; `.trim(), 
              '')

1

以下是使用正则表达式演示骆驼式案例字符串到句子字符串的链接。

输入项

myCamelCaseSTRINGToSPLITDemo

输出量

my Camel Case STRING To SPLIT Demo


这是用于将驼峰式案例转换为句子文本的正则表达式

(?=[A-Z][a-z])|([A-Z]+)([A-Z][a-rt-z][a-z]\*)

$1 $2作为替代。

单击以查看正则表达式上的转换


在答案正文中提供链接中的相关内容。
Grant Miller

1

输入 javaScript

输出 Java脚本

   var text = 'javaScript';
    text.replace(/([a-z])([A-Z][a-z])/g, "$1 $2").charAt(0).toUpperCase()+text.slice(1).replace(/([a-z])([A-Z][a-z])/g, "$1 $2");

1

基于RegEx的另一种解决方案。

respace(str) {
  const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g;
  return str.replace(regex, '$& ');
}

说明

上面的RegEx包含两个由OR运算符分隔的相似部分。上半年:

  1. ([A-Z]) -匹配大写字母...
  2. (?=[A-Z][a-z]) -后跟一系列大写和小写字母。

当应用于序列FOo时,它有效地匹配其F字母。

或第二种情况:

  1. ([a-z]) -匹配小写字母...
  2. (?=[A-Z]) -后跟一个大写字母。

当应用于序列barFoo时,这将有效地匹配其r字母。

找到所有替换候选者后,最后要做的是用相同的字母替换它们,但使用附加的空格字符。为此,我们可以使用它'$& '作为替换,它将解析为匹配的子字符串,后跟一个空格字符。

const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g
const testWords = ['ACoolExample', 'fooBar', 'INAndOUT', 'QWERTY', 'fooBBar']

testWords.map(w => w.replace(regex, '$& '))
->(5) ["A Cool Example", "foo Bar", "IN And OUT", "QWERTY", "foo B Bar"]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.