如何拆分camelCase字符串并检查每个拆分词是不是是数组的一部分?
Posted
技术标签:
【中文标题】如何拆分camelCase字符串并检查每个拆分词是不是是数组的一部分?【英文标题】:How to split a camelCase string and check if each split word is part of an array or not?如何拆分camelCase字符串并检查每个拆分词是否是数组的一部分? 【发布时间】:2019-06-21 21:05:44 【问题描述】:假设我有一个 单词数组 和几个 camelCase 字符串,如下所示:
var arr = ["hello", "have", "a", "good", "day", "***"];
var str1 = "whenTheDayAndNightCollides";
var str2 = "HaveAGoodDay";
var str3 = "itIsAwfullyColdDayToday";
var str4 = "Hello***";
如何将camelCase
单词拆分为单独的字符串,将每个拆分字符串(转换为小写)与arr
数组元素进行比较,如果每个拆分字符串都是指定数组的一部分,则返回true
?
"whenTheDayAndNightCollides" // should return false since only the word "day" is in the array
"HaveAGoodDay" // should return true since all the words "Have", "A", "Good", "Day" are in the array
"itIsAwfullyColdDayToday" // should return false since only the word "day" is in the array
"Hello***" // should return true since both words "Hello" and "***" are in the array
正如其他SO thread 中所建议的那样,我尝试使用every() 方法和indexOf() 方法来测试是否可以在数组中找到每个拆分字符串,如以下代码所示片段,但它不起作用:
var arr = ["hello", "have", "a", "good", "day", "***"];
function checkString(wordArray, str)
// split the camelCase words
var x = str.replace(/([A-Z])/g, ' $1').split(" ");
return x.every(e =>
return wordArray.indexOf(e.toLowerCase()) >= 0;
);
console.log("should return true ->" + checkString(arr, "Hello***"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
我做错了什么?
【问题讨论】:
【参考方案1】:对于这种特殊情况,我将使用lookahead assertion(?=...)
,这是一个非捕获构造,我将直接与String::split() 方法一起使用。当字符串以大写字母开头时,这将解决数组上额外生成的empty string
元素的问题。我也会尝试Array::includes() 以换取indexOf()
const arr = ["hello", "have", "a", "good", "day", "***"];
function checkString(wordArray, str)
return str.split(/(?=[A-Z])/g).every(
e => wordArray.includes(e.toLowerCase())
);
console.log(
"checkString(arr, 'Hello***') =>",
checkString(arr, "Hello***")
);
console.log(
"checkString(arr, 'itIsAwfullyColdDayToday') =>",
checkString(arr, "itIsAwfullyColdDayToday")
);
.as-console background-color:black !important; color:lime;
.as-console-wrapper max-height:100% !important; top:0;
【讨论】:
之前没想过使用lookahead assertion
。绝对是一个很好的方法。谢啦。 +1【参考方案2】:
在进行比较之前,您必须将拆分字符串转换为小写。
此外,当字符串的第一个字母为大写时,您必须删除由replace
插入的列表开头的空字符串。
您可以使用includes
代替indexOf
。
var arr = ["hello", "have", "a", "good", "day", "***"];
function checkString(wordArray, str)
return str.replace(/([A-Z])/g, ' $1')
.split(" ") // split on spaces
.map(s => s.toLowerCase())
.filter(s => s)
.every(e => wordArray.includes(e));
console.log("should return true -> " + checkString(arr, "Hello***"));
console.log("should return false -> " + checkString(arr, "itIsAwfullyColdDayToday"));
【讨论】:
我指定了 toLowerCase() 但之前复制了错误的 sn-p。在字符串以大写字母开头的情况下,我忽略了空拆分字符串。谢啦。 +1.filter(s => s)
的目的是什么?
@Taki ["","hello"].filter(f => f)
将产生["hello"]
,这只是摆脱带有空白字符串的元素的简单方法。
@Taki 我认为过滤器会删除当Hello
被<space_here>Hello
替换然后由space
拆分生成数组["", "Hello"]
时生成的空字符串。在他的帖子的上一版本中对此有评论。
这是一个很好的答案,但 lookahead assertion
方法更简洁 imo。 lookahead assertion
不是处理生成的空字符串,而是首先确保不会生成空字符串。【参考方案3】:
你很接近,但有两个问题:
其中一个在您的 str.replace
上,当您在字符串的开头有一个大写字母时,它会返回类似 ["", "Hello", "***"]
的内容。
第二个在你的比较中 wordArray.indexOf()
它是区分大小写的,所以你需要添加 toLowerCase()
所以它最终是这样的:wordArray.indexOf(e.toLowerCase())
var arr = ["hello", "have", "a", "good", "day", "***"];
function checkString(wordArray, str)
var x = str.replace(/([A-Z])/g, ' $1').split(" "); // split the camelCase words
//filter spaces
var filtered = x.filter(s => s != '');
return filtered.every(e =>
return wordArray.indexOf(e.toLowerCase()) >= 0;
);
console.log("should return true ->" + checkString(arr, "Hello***"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
【讨论】:
我指定了 toLowerCase() 但之前复制了错误的 sn-p。在字符串以大写字母开头的情况下,我忽略了空拆分字符串。谢啦。 +1【参考方案4】:一些问题:首先,所有arr
值都以小写字母开头,但是您的驼峰式测试(当然)包含大写字母。所以我换了
wordArray.indexOf(e)
与
wordArray.indexOf(e.toLowerCase())
其次,由于您的第一个测试用例以大写字母开头,因此您的正则表达式会添加一个空格,然后将split
变成它自己的“单词”。为了解决这个问题,我刚刚将!e ||
添加到every
条件中,因此对于前导大写字母生成的空字符串,它将始终返回true。
var arr = ["hello", "have", "a", "good", "day", "***"];
function checkString(wordArray, str)
var x = str.replace(/([A-Z])/g, ' $1').split(" "); // split the camelCase words
return x.every(function (e) return !e || wordArray.indexOf(e.toLowerCase()) >= 0; );
console.log("should return true ->" + checkString(arr, "Hello***"));
console.log("should return false ->" + checkString(arr, "itIsAwfullyColdDayToday"));
【讨论】:
我指定了 toLowerCase() 但之前复制了错误的 sn-p 但这是一种处理初始空字符串的好方法。 +1【参考方案5】:这是一个非常简单的版本。
const checkString = arr => str => str
.split(/(?=[^a-z])/)
.every(s => arr.includes(s.toLowerCase()))
const arr = ["hello", "have", "a", "good", "day", "***"]
console.log(checkString(arr)('whenTheDayAndNightCollides'))
console.log(checkString(arr)('HaveAGoodDay'))
console.log(checkString(arr)('itIsAwfullyColdDayToday'))
console.log(checkString(arr)('Hello***'))
当然你也可以命名中间函数:
const correct = checkString(arr)
correct('HaveA***Day') //=> true
【讨论】:
以上是关于如何拆分camelCase字符串并检查每个拆分词是不是是数组的一部分?的主要内容,如果未能解决你的问题,请参考以下文章
使用php preg_match(正则表达式)将camelCase单词拆分为单词