使用正则表达式在驼峰式字符串中添加空格

21

我从add a space between two words得到了这个问题。

要求:将驼峰式字符串分割,并在大写字母之前加上空格,该大写字母后面跟着一个小写字母或什么也没有。在大写字母之间不应该有空格。

例如:CSVFilesAreCoolButTXT是一个字符串,我希望它呈现为CSV Files Are Cool But TXT

我用正则表达式解决了这个问题:

"LightPurple".replace(/([a-z])([A-Z])/, '$1 $2')

如果您有超过2个单词,那么您需要使用g标志来匹配它们全部。

"LightPurpleCar".replace(/([a-z])([A-Z])/g, '$1 $2')

如果您想分割像CSVFile这样的单词,那么您可能需要使用这个正则表达式:

"CSVFilesAreCool".replace(/([a-zA-Z])([A-Z])([a-z])/g, '$1 $2$3')

但它仍然不能按照我提出的要求提供服务。


你的最后一个正则表达式只在以大写字母结尾时失败。例如,...ButTXT - Oscar Mederos
6个回答

33
var rex = /([A-Z])([A-Z])([a-z])|([a-z])([A-Z])/g;

"CSVFilesAreCoolButTXT".replace( rex, '$1$4 $2$3$5' );
// "CSV Files Are Cool But TXT"

同时也

"CSVFilesAreCoolButTXTRules".replace( rex, '$1$4 $2$3$5' );    
// "CSV Files Are Cool But TXT Rules"

匹配正则表达式模式的主题字符串的文本将被替换为替换字符串'$1$4 $2$3$5',其中$1$2等引用模式的捕获组()所匹配的子字符串。

$1引用第一个([A-Z])子模式匹配的子字符串,$3引用第一个([a-z])子模式匹配的子字符串等。

由于备选字符|,为了做出匹配,正则表达式必须匹配([A-Z])([A-Z])([a-z])子模式或([a-z])([A-Z])子模式中的任意一个,因此如果匹配成功,多个捕获组将保持未匹配状态。这些捕获组可以在替换字符串中引用,但它们对其没有影响 - 实际上,它们将引用一个空字符串。

替换字符串中的空格确保每次匹配时都会在主题字符串中插入一个空格(尾随的g标志意味着正则表达式引擎会查找多个匹配)。


2
我很想看到你定义的正则表达式的解释,这样读者和新手就可以知道所有这些1-2-3-4-5都在发生什么事情。 - KMX
好的,对于我最初的要求来说,这是最好的。现在我提出了一些更多的压力。所以让我们在这个帖子下继续努力吧。请阅读更新内容。 - KMX
1
@KMX。我建议您提出一个新问题,以便其他人有机会获得被接受答案的信用。 - MikeM
(笨蛋)好的!它很快就会被创建。 - KMX
请看这里:https://dev59.com/WW_Xa4cB1Zd3GeqP2pIG - KMX

6
如果第一个字符始终是小写字母。
'camelCaseString'.replace(/([A-Z]+)/g, ' $1')

如果第一个字符是大写字母。

'CamelCaseString'.replace(/([A-Z]+)/g, ' $1').replace(/^ /, '')

3

在.NET中使用正则表达式拆分CamelCase:

Regex.Replace(input, "((?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z]))", " $1").Trim();

示例:

Regex.Replace("TheCapitalOfTheUAEIsAbuDhabi", "((?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z]))", " $1").Trim();

输出:阿联酋的首都是阿布扎比


Trim() 看起来似乎不是必需的,至少在将解决方案迁移到 JavaScript 时不是。 - JP Damstra

2
这对我起了作用。
let camelCase = "CSVFilesAreCoolButTXTRules"
let re = /[A-Z-_\&](?=[a-z0-9]+)|[A-Z-_\&]+(?![a-z0-9])/g
let delimited = camelCase.replace(re,' $&').trim()

上述代码适用于我几乎所有的使用情况。我有一些特殊情况,其中“&”和“_”应被视为大写字符的等效形式。
  • ThisIsASlug ---> This Is A Slug
  • loremIpsum ---> lorem Ipsum
  • PAGS_US ---> PAGS_US
  • TheCapitalOfTheUAEIsAbuDhabi ---> The Capital Of The UAE Is Abu Dhabi
  • eclipseRCPExt ---> eclipse RCP Ext
  • VALUE ---> VALUE
  • SG&A ---> SG&A
简要说明:
[A-Z-_\&](?=[a-z0-9]+)
//Matches normal words i.e. one uppercase followed by one or more non-uppercase characters 


[A-Z-_\&]+(?![a-z0-9]) 
//Matches acronyms & abbreviations i.e. a sequence of uppercase characters that are not followed by non-uppercase characters

请查看这里的正则表达式示例:Check out the regexr fiddle here

0

使用前后查找的方式在Javascript中进行驼峰式替换:

"TheCapitalOfTheUAEIsAbuDhabi".replace(/([A-Z](?=[a-z]+)|[A-Z]+(?![a-z]))/g, ' $1').trim()
// "The Capital Of The UAE Is Abu Dhabi"

"TheCapitáÖfTheUAEIsAbuDhabi".replace(/(A-Z|[A-Z]+(?![a-z]))/g, ' $1').trim()在Firefox的JS引擎中失败。 - Ned Martin
需要考虑 Unicode 字符。上面的方法只适用于 ASCII 字符子集。 - Zach Wymer

0
对于那些希望将除首字母外的所有单词也转换为小写的人来说。
function PascalCaseToText(str) {
  return str.replace(/([a-z])([A-Z])/g, function(_, g1, g2) { return g1 + ' ' + g2.toLowerCase();  })
}

PascalCaseToText("SomePascalString");
// Some pascal string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接