JavaScript匹配字符串到部分匹配

8
如何在Javascript中进行部分字符串匹配?
例如,匹配“Alf”
- 'Alfred' -> true - 'Alf' -> true - 'alf' -> true - 'al' -> true - 'altered' -> false - 'half' -> false - '' -> false - 'bob' -> false

https://jsfiddle.net/zbzc5tqe/1/

我希望在编程中能更少使用JavaScript内置函数。

var arr = ['Alfred', 'Alf', 'alf', 'al', 'altered', 'half', '', 'bob'];

arr.forEach(function(element) {
  add(element + "->" + matches(element, 'Alf'));
});

function ignoreCase(s1, s2) {
  var needleRegExp = new RegExp('^' + s2 + "$", "i");
  return needleRegExp.test(s1)
}

function partializer(string) {
  var out = [];
  for (var i = 1; i < string.length; i++) {
    out.push(string.slice(0, i));
  }
  return out;
}

function matches(text, partial) {
  var parts = partializer(partial);
  for (var i = 0; i < parts.length; i++) {
    if (startsWith(text, parts[i])) {
      return true;
    }
  }
  return false;
}

function startsWith(text, element) {
  var s2 = text.split(0, element.length - 1);
  return ignoreCase(element, s2);
}

function add(text) {
  var olList = document.getElementById('list');
  var newListItem = document.createElement('li');
  newListItem.innerText = text;
  olList.appendChild(newListItem);
}
<ol id="list">
</ol>


我建议研究正则表达式 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions - Hamms
3个回答

9

看起来你只是想知道一个字符串是否以子字符串开头:

function test(arr, sub) {
  sub = sub.toLowerCase();
  return arr.map(str => str
    .toLowerCase()
    .startsWith(sub.slice(0, Math.max(str.length - 1, 1)))
  );
}

var arr = ['Alfred', 'Alf', 'alf', 'al', 'altered', 'half', '', 'bob'];

var results = test(arr, 'alf');
console.log(results);


啊,是的,我把这个看反了。没想到要修剪“输入”,谢谢。 - Ryan Leach
有一个警告,即 str.toLowerCase 不支持国际化。 - Ryan Leach
我也没想到 startsWith 在输入为空时会这样工作。 - Ryan Leach
@RyanTheLeach,国际化方面你说得对。另外,根据你的浏览器支持情况,startsWith可能不被支持,但是,将其替换为indexOf == 0很容易。 - KevBot
1
@RyanTheLeach,我添加了两个改进。1、在检查时子字符串应该是小写的。2、sub.slice 应该始终至少有一个最小值,否则仅传递 'a' 将产生错误的结果。 - KevBot
显示剩余2条评论

4
使用.indexOf查找字符串中是否存在匹配项。请参阅。
function matches(text, partial) {
  return text.toLowerCase().indexOf(partial.toLowerCase()) > -1;
}

function matchesCase(text, partial) {
  return text.indexOf(partial) > -1;
}

https://jsfiddle.net/zbzc5tqe/3/

如果您只想匹配区分大小写的内容,请使用matchesCase()函数。


1
al 应该是 true,而 half 应该是 false - KevBot
并不是真正意识到‘al’应该是true,而‘half’应该是false。 同意你的答案如果用indexOf == 0替换会更好,因为如果使用startWith方法,‘A’将会是false。 - Chris
我已经编辑添加了一个额外的测试用例:https://jsfiddle.net/zbzc5tqe/5/ - Ryan Leach

2

之前没有检查部分使用情况,您可以使用类似以下的正则表达式:

   var value = 'ALF';
   var comparor = value.slice(0, element.length - 1);
   var regexp = new RegExp("^"+comparor, "i");
   regexp.test(element);

var arr = ['Alfred', 'Alf', 'alf', 'al', 'half', '', 'bob'];
var value = '00';
arr.forEach(function(element) {
    var comparor = (element.length > 1 ) ? value.slice(0, element.length - 1) : value;
    var regexp = new RegExp("^"+comparor, "i");
  add(element + "->" + regexp.test(element));
});



function add(text) {
  var olList = document.getElementById('list');
  var newListItem = document.createElement('li');
  newListItem.innerText = text;
  olList.appendChild(newListItem);
}
<ol id="list">
</ol>


你的答案未通过以下测试用例:'al' -> true。 - Ryan Leach
抱歉晚了三年才评论,但是将单个字符作为值传递,例如“o”,会失败,它会返回空值(从您的jsFiddle示例中),而实际上应该是false。 - Andrew
1
@Andrew,好发现,我没有检查所有的测试用例 :) 已经在代码中进行了更改,以包括您提到的用例。显然,在单个字符或空字符上执行切片并将其减去1将导致空值而不是预期值。 - subramanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接