【问题标题】:How do I make JavaScript's replaceAll() treat strings with both lower case and upper case as if they were lower case?如何使 JavaScript 的 replaceAll() 将小写和大写的字符串视为小写?
【发布时间】:2021-02-03 10:15:26
【问题描述】:

在我的<div contenteditable="true"> 中,用户可以输入单词“star”,该单词会立即被星号替换。

如果用户输入全小写的“星”,则会显示:★

如果用户全部输入大写字母,则会显示:☆

我需要什么:如果用户输入的单词“star”混合了大小写字母(例如:staR、Star、STaR...),应该显示:★

我的第一个想法是使用toLowerCase(),但由于转换发生在onInput,并且只有在输入整个单词后才会转换文本,因此使用它将无法输入“STAR”,全部大写。

有什么想法吗?

我愿意接受jQuery 解决方案。

这是我的代码:

JSFiddle

// Autofocus the div:
document.getElementById("editableDiv").focus();

// Makes the conversion possible:
String.prototype.allReplace = function(obj) {
  var retStr = this;
  for (var x in obj) {
    retStr = retStr.replace(new RegExp(x, 'g'), obj[x]);
  }
  return retStr;
};

// Converts
function convert() {
  var str = document.getElementById("editableDiv").innerHTML;
  var white = str.allReplace({
    'STAR': '☆',
    'DIAMOND': '◇'
  });
  var black = white.allReplace({
    'star': '★',
    'diamond': '◆'
  });

  document.getElementById("editableDiv").innerHTML = black;

  // Move caret to the end:
  var contentEditableElement = document.getElementById("editableDiv");
  var range, selection;
  if (document.createRange) {
    range = document.createRange();
    range.selectNodeContents(contentEditableElement);
    range.collapse(false);
    selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
  } else if (document.selection) {
    range = document.body.createTextRange();
    range.moveToElementText(contentEditableElement);
    range.collapse(false);
    range.select();
  }
}
body {
  padding: 10px;
  font-family: sans-serif;
}

div {
  padding: 5px 20px;
  width: 200px;
  border: solid 1px #000;
  outline: 0;
  line-height: 2;
  font-size: 1.5em;
}
<div id="editableDiv" contenteditable spellcheck="false" oninput="convert();"></div>

【问题讨论】:

  • 所以你使用的是reg exp,添加case标志'gi'

标签: javascript uppercase case-insensitive lowercase replaceall


【解决方案1】:

首先我建议使用现有的replaceAll

第二个你正在使用正则表达式!别担心,这并不复杂(为了你的目的) 我建议您分两步进行:

1 - 将所有 'STAR' 替换为 ☆

2 - 然后用★替换“不考虑情况”'star'

而“不考虑情况”意味着只在正则表达式中使用标志i ;)

function replaceMyStuff(str) {
  var r = str.replaceAll('STAR', '☆')
             .replaceAll(/star/gi, '★')
             .replaceAll('DIAMOND', '<>')
             .replaceAll('stuff', 'replacedStuff');
  return r;
}

console.log(replaceMyStuff('star STAR StAr STAR STAr stuff'));

如果你对它更舒服,你可以写:

 new RegExp('star', 'gi')

/star/gi基本一样

然后你可以用它来替换所有你想要的:

 var str = document.getElementById("editableDiv").innerHTML;
 var replacedString = replaceMyStuff(str);

【讨论】:

  • 使用我的代码,我是否必须将'star': '★', 行替换为/star/gi, '★'?因为我试过了,它不起作用。我可能做错了什么……
  • 你应该试着理解你在做什么......人们不会给你最终的代码......即使这是我几乎完成的......检查答案我已经更新了...
【解决方案2】:

您可以使用严格相等比较 (===) 运算符对目标字符串进行检查,如下所示:

if (string.toLowerCase() === 'star') {

  if (string === 'STAR') {
    output = '☆';
  }

  else {
    output = '★';
  }
}

工作示例:

const paragraphs = [...document.getElementsByTagName('p')];

const convertParagraph = (paragraph) => {

  let paragraphArray = paragraph.textContent.split(' ');
  
  for (let i = 0; i < paragraphArray.length; i++) {
  
    if (paragraphArray[i].toLowerCase() === 'star') {
    
      if (paragraphArray[i] === 'STAR') {
        paragraphArray[i] = '☆';
      }
    
      else {
        paragraphArray[i] = '★';
      }
    }
  }
  
  paragraph.textContent = paragraphArray.join(' ');
}

paragraphs.forEach(paragraph => convertParagraph(paragraph));
<div>
<p>STAR This is a test.</p>
<p>star This is another test.</p>
<p>sTAr This is a third test.</p>
</div>

【讨论】:

  • 但用户将能够键入“星号”以外的内容。我不想转换除“star”、“STAR”以及两者的任何混合之外的任何其他文本。如何在我的代码中实现这一点?
  • 为了使用上述条件,您可以执行以下操作: 1) 抓取整个文本; 2)使用空格作为分隔符将其拆分为数组; 3)遍历数组检查/处理每个元素; 4)将数组重新连接成一个字符串。这是一种不涉及正则表达式的方法。或者您可以选择此页面上使用正则表达式的答案之一(我赞成@Seba99,我认为这非常好)。
  • 我添加了一个工作示例来说明我在上面评论中的意思。
猜你喜欢
  • 1970-01-01
  • 2011-10-10
  • 2018-09-07
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 2011-01-16
相关资源
最近更新 更多