简体   繁体   English

如何在 JavaScript 中将字符串转换为脊柱大小写?

[英]How do I convert a string to spinal case in JavasScript?

I am stuck on this coding challenge Spinal Tap Case from freeCodeCamp.我被 freeCodeCamp 的这个编码挑战Spinal Tap Case困住了。 Essentially I don't know how to get the last check to execute.本质上,我不知道如何执行最后一次检查。

This is the last check: spinalCase("AllThe-small Things") should return "all-the-small-things"这是最后一次检查: spinalCase("AllThe-small Things") should return "all-the-small-things"

And this is my code:这是我的代码:

function spinalCase(str) {
    var outputString, 
              newstr,
              pattern1 = new RegExp(/[_\s]/, 'g'),
              pattern2 = new RegExp(/(?=[A-Z])/, 'g'),
              stringTest1 = pattern1.test(str),
              stringTest2 = pattern2.test(str);

         if(stringTest1)  {
                outputString = str.replace(pattern1, '-');
                newstr = outputString.toLowerCase();
          } else if(stringTest2) {
               str.split(/(?=[A-Z])/).join(' ');
                outputString = str.replace(pattern2, '-');
                newstr = outputString.toLowerCase();
          } else if (stringTest1 && stringTest2){
                outputString = str.replace(pattern1, '-');
                outputString = str.replace(pattern2, '-');
                newstr = outputString.toLowerCase();
          }

  return newstr;

}

I do realize the last else if condition should go first however I didn't get the syntax right.我确实意识到最后一个else if条件应该首先出现,但是我没有得到正确的语法。

Thanks in advance!提前致谢!

Here is how I recommend doing it:以下是我推荐的做法:

function sp(str) {
  var spinal = str.replace(/(?!^)([A-Z])/g, ' $1')
                .replace(/[_\s]+(?=[a-zA-Z])/g, '-').toLowerCase();
  return spinal 
}

JsBin Example JsBin 示例

as far as your code, you check for:至于你的代码,你检查:

if test1 else if test2 , then else if test1 and test2 , the logic is not correct: if test1 else if test2 , then else if test1 and test2 ,逻辑不正确:

you could try to adding a !test2 or !test1 to the first if checks to get it working:您可以尝试将!test2!test1到第一个 if 检查以使其正常工作:

if (stringTest1 && !stringTest2)...

EDIT:编辑:

here is how you can get your code to fire in that last else if, I put a console.log in there to show you here:下面是如何让你的代码在最后一个 else 中触发,如果我在那里放了一个 console.log 来向你展示:

JSBin Example JSBin 示例

function spinalCase(str) {
    var outputString, 
              newstr,
              pattern1 = new RegExp(/[_\s]/, 'g'),
              pattern2 = new RegExp(/(?=[A-Z])/, 'g'),
              stringTest1 = pattern1.test(str),
              stringTest2 = pattern2.test(str);

         if(stringTest1 && !stringTest2)  {
                outputString = str.replace(pattern1, '-');
                newstr = outputString.toLowerCase();
          } else if(!stringTest1 && stringTest1) {
               str.split(/(?=[A-Z])/).join(' ');
                outputString = str.replace(pattern2, '-');
                newstr = outputString.toLowerCase();
          } else if (stringTest1 && stringTest2){
                console.log('were in the last else!!!');
                outputString = str.replace(pattern1, '-');
                outputString = str.replace(pattern2, '-');
                newstr = outputString.toLowerCase();
          }

  return newstr;

}

Here's my solution, simple with regex and works for all cases这是我的解决方案,使用正则表达式很简单,适用于所有情况

function spinalCase(str) {
  return str.replace(/([A-Z])/g,' $1') /*Find all cap and add space at the start*/
        .replace(/[^A-Za-z0-9]/g,' ') /*Find all non alpha numeric and replace it with space*/
        .replace(/\s{1,}/g,"-") /*Convert all spaces to -*/
        .replace(/^\-|[\-]$/g,'') /*Slice - at the start and end*/
        .toLowerCase(); /*LowerCase it*/
}

here's my solution, a bit less heavy on the regex:这是我的解决方案,对正则表达式不那么重:

function spinalCase(str) {
  var newStr = str[0];

  for (var j = 1; j < str.length; j++) {
    // if not a letter make a dash
    if (str[j].search(/\W/) !== -1 || str[j] === "_") {
      newStr += "-";
    }
    // if a Capital letter is found 
    else if (str[j] === str[j].toUpperCase()) {
      // and preceded by a letter or '_'
      if (str[j-1].search(/\w/) !== -1 && str[j-1] !== "_") {
        // insert '-' and carry on
        newStr += "-";
        newStr += str[j];
      }
      else {
        newStr += str[j];
      }
    }
    else {
        newStr += str[j];
    }
  }

  newStr = newStr.toLowerCase();
  return newStr;
}
function spinalCase(str) {

  // any string followed by upperCase letter
  var  re = /(?=[A-Z])/g;  

  // any string followed by space and upperCase/lowerCase letter 
  var  re2=/(?=\s[A-Z]|\s[a-z])/g;

  // any string of 2 or more '-'
  var re3 = new RegExp("-{2,}", "g");

  var space = new RegExp(" ","g");
  var hyphen = new RegExp("_","g");

  str = str.replace(hyphen,"-");
  str = str.replace(re, '-');   
  str = str.replace(re2,"-");
  str = str.replace(re3,"-"); 
  str = str.replace(space,"");
  str = str.toLowerCase();
  if(str.slice(0,1)== '-'){
    str = str.replace("-","");  
  }     
  return str;
}

spinalCase('This Is Spinal Tap');
function spinalCase(str) {
  var newStr = '';
  var arr = str.split('');
  for (var i = 0; i < arr.length; i += 1) {
    if (i > 0) {
      if (arr[i] >= 'A' && arr[i] <= 'Z') {
        if (arr[i - 1] >= 'a' && arr[i - 1] <= 'z') {
          newStr += '-';
          newStr += arr[i].toLowerCase();
          continue;
        }
      }
      else if (arr[i] === ' ' || arr[i] === '_') {
        newStr += '-';
        continue;
      }
    }
    newStr += arr[i].toLowerCase();
  }
  return newStr;
}

spinalCase("AllThe-small Things");
function spinalCase(str) {
//Split the string at one of the following conditions 
        //a whitespace character [\s] is encountered
        //underscore character [_] is encountered
        //or by an uppercase letter [(?=[A-Z])]
//Join the array using a hyphen (-)
//Lowercase the whole resulting string 

   return str.split(/\s|_|(?=[A-Z])/).join('-').toLowerCase(); 

}

I was stuck on this too, but found a simpler solution:我也被困在这个问题上,但找到了一个更简单的解决方案:

 function spinalCase(str) { const regex =new RegExp(/(([AZ]|[az])[az]+)/,'g'); str=str.match(regex); return str.join('-').toLowerCase(); } console.log(spinalCase('AllThe-small things'));

A beginner friendly solution:初学者友好的解决方案:

function spinalCase(str) {
//change camelCase to title case(i.e. change 'markIsHere' to 'Mark Is Here') 
    let newStr = str.replace(/([a-z])([A-Z])/g, ('$1 $2'));
//replace space with '-'
    newStr = newStr.replace(/ /g, '-');
//replace underscores with '-'
    newStr = newStr.replace(/_/g,'-');
//change the result to lowercase
    return newStr.toLowerCase()
}
function spinalCase(str) {

  // Create a variable for the white space and underscores
  var regex = /\s+|_+/g;

  // Replace low-upper case to low-space-uppercase
  str = str.replace(/([a-z])([A-Z])/g, '$1 $2');

  // Replace space and underscore with dashes
  return str.replace(regex, '-').toLowerCase();

}
function insert(arr){
    arr = arr.split("");
    for(let i in arr){
      if (/[A-Z]/.test(arr[i])&& i>0){
        arr[i] = "-" + arr[i];
      }
    }
    arr = arr.join("");
    return arr;
  }

function spinalCase(str) {
  
  str = str.split(/\s+|_/);
  str = str.map(item=>insert(item));
  str = str.join("-");
  str = str.toLowerCase();
  return str;
  
}

I've come up with the following.我想出了以下内容。 For the FCCamp purpose it works出于 FCCamp 的目的,它可以工作

function spinalCase(str) {
  return str
    .split(/(?=[A-Z])/)
    .join()
    .split(/[_\W+]/)
    .join(' ')
    .split(/\s+/)
    .join('-')
    .toLowerCase()
}
spinalCase("AllThe-small Things");

I have no illusions that anybody is going to care now ;), but I would have searched for positions in-between words, as indicated by capital letters, and placed hyphens there instead.我不幻想现在有人会关心;),但我会搜索单词之间的位置,如大写字母所示,并在那里放置连字符。 For example:例如:

 const spinalCase = (str) => { let regex = /(?:\\B|[ _])(?=[AZ])/g; return str.replace(regex, '-').toLowerCase(); } console.log(spinalCase('AllThe-small Things'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM