有一种优雅的方法可以将变量名中的单个单词提取到数组中吗?

时间:2017-06-06 14:44:21

标签: javascript arrays regex

基本上我想这样做:

我收到一个字符串"myVariableName"并将其转换为:["my", "variable", "name"]

我尝试使用正则表达式执行此操作,但似乎在结束数组中得到了很多未定义的内容。在这种情况下,变量名称的两种可能情况是驼峰式和上部蛇形。

const matchVariableNames =  /(\b[a-z]+)|([A-Z][a-z]+)|(\b[A-Z]+)|(_[A-Z]+)/g;
const variableName = 'myVariable';
let words = [];
let regexMatches;

while (regexMatches = matchVariableNames.exec(variableName)) {
  regexMatches.forEach((match) => {
    words.push(match);
  }); 
};

输出:

["my", "my", undefined, undefined, undefined, "Variable", undefined, "Variable", undefined, undefined]
undefined

3 个答案:

答案 0 :(得分:3)

您可以使用带有大写字母的正向前瞻。然后只映射小写字母。

var string = 'myVariableName',
    array = string.split(/(?=[A-Z])/).map(a => a.toLowerCase());
    
console.log(array);

答案 1 :(得分:2)

我认为正则表达式不适合这个。 (我不接受Regular expression to identify CamelCased words with leading uppercase letter作为副本,因为问题没有要求正则表达式。)

我读它的方式你要解析用camelcase写的字。我立即想象"DOMElement"PDFParser"等特殊情况。我希望输出为[ "DOM", "Element" ][ "PDF", "Parser" ]。我想我们可以编写一个类似的功能。

function parseWordsFromCamelCaseString(string) {
  var i, words, last_word_char, last_case, current_case;
  words = [];
  last_word_start = 0;
  last_case = null; // false=lower, true=upper

  for (i = 0; i < string.length; i += 1) {
    current_case = string[i].toUpperCase() === string[i];
    if (last_case !== null && current_case !== last_case) {
      if (current_case === true) { // lowercase to uppercase transition
        words.push(string.substring(last_word_start, i));
        last_word_start = i;
      } else { // uppercase to lowercase transition
        if (last_word_start < i - 1) {
          words.push(string.substring(last_word_start, i - 1));
        }
        last_word_start = i - 1;
      }
    }
    last_case = current_case;
  }
  if (last_word_start < i - 1) {
    words.push(string.substring(last_word_start, i));
  }
  return words;
}

console.log(parseWordsFromCamelCaseString("fooBar"));
console.log(parseWordsFromCamelCaseString("parseWordsFromCamelCaseString"));
console.log(parseWordsFromCamelCaseString("DOMElement"));
console.log(parseWordsFromCamelCaseString("fooDOMElement"));

输出

["foo", "Bar"]
["parse", "Words", "From", "Camel", "Case", "String"]
["DOM", "Element"]
["foo", "DOM", "Element"]

它也适用于"foo"(无案例转换)和""(空字符串)。

答案 2 :(得分:-1)

我创造了这个:

x = 'myVariableName';
const isUpper = e => (e === e.toUpperCase());
[].reduce.call(x, (words, letter, i) => {
  if(isUpper(letter)) words.push([letter]);
  else {
    let length = words.length-1,
        word = words[length];
    words[length] = word+letter;
  }
  return words;
}, [[]]);

返回["my", "Variable", "Name"]

它非常优雅吗?我们可以争取它,但我确定比你的RegExp更多。 :P