【问题标题】:Is there an elegant way to extract individual words from variable names into an array?有没有一种优雅的方法可以将变量名中的单个单词提取到数组中?
【发布时间】:2017-11-07 15:41:50
【问题描述】:

基本上我想这样做:

我得到一个字符串"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

【问题讨论】:

  • "myVariableName".match(/((?:^|[A-Z])[a-z]+)/g) 从技术上讲,一些非字母字符可以用作 var 名称,但这可能就足够了,具体取决于您的 var 命名约定
  • console.log( "myVariableName" .replace(/^[a-z]|[A-Z]/g, function(v, i) { return (i === 0 ? "":" ")+ v.toLowerCase(); }).split(" ") )

标签: javascript arrays regex


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我认为正则表达式不适合这种情况。 (我不接受 Regular expression to identify CamelCased words with leading uppercase letter 重复,因为该问题不要求正则表达式 persé)。

    我读它的方式是你想解析用驼峰写的单词。我立刻想到了特殊情况,例如"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"(无大小写转换)和""(空字符串)。

    【讨论】:

    • 那你认出javascript-regex-camelcase-to-sentence 是重复的吗?
    • @mplungjan 我不明白为什么。没有非正则表达式答案。而且他们都没有正确处理我概述的(不是那么)特殊情况。
    【解决方案3】:

    我已经创建了这个:

    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

    【讨论】:

    • "myPDFFile" 这样的输入会中断。它返回[ "my", [ "p" ], [ "D" ], [ "F" ], "File" ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 2011-01-15
    相关资源
    最近更新 更多