字符串匹配类的问题,尝试正则

130 阅读3分钟

最近在看数据结构和算法,努力总结出道~

基础:创建正则

创建正则,两种方式:

  • /ab+c/gi,适用于静态的正则表达式
  • new RegExp("ab+c","gi"),适用于动态的表达式

后面的gi是可选标志,可不写,表示允许全局和不分大小写搜索等,

regx2

基础:JS 怎么用正则

JS 使用正则,无外乎调用方法,一个是正则对象的两个方法 exectest 方法, 一个是字符串的 5 个方法matchmatchAllreplacesearchsplit 方法。

regx1

一般常用的估计就是exectestmatchreplace,注意是哪种对象的方法,确保调用准确。

  • 看下字符串里有没有匹配的字符串,一般用test,返回true/false,如/^hello/.test('hello world!')返回true
  • 看下字符串里匹配的字符串具体有哪些,一般用match,返回数组/null,如'Maria has a sheep named Yan'.match(/[A-Z]/g),返回['M','Y']
  • 看下字符串里匹配的字符串的详细信息,一般用exec,返回数组/null,需要第一个的时候直接使用,但需要所有的详细信息的时候,需要循环。因为 exec 只返回一个匹配字符串的详细信息
function getMatch(str, reg) {
  let resArray = [];
  let res = reg.exec(str);

  while (res) {
    resArray.push(res);
    res = reg.exec(str);
  }
  return resArray
}
console.log(getMatch('table football, foosball',/foo*/g))

reg2

  • 字符串里面的内容需要替换,一般用replace,返回新的字符串,但不改变原始字符串。replace第二个参数可以是回调函数,返回值就是替换的值,复杂的情况可以结合函数使用。
var str = 'Twas the night before Xmas...';
var newstr = str.replace(/xmas/i, 'Christmas');
// Twas the night before Christmas...
console.log(newstr);

练习:搜索字符串

string3

add其实就是存储操作,为了后期查找更快速,以字符串的长度为 key,相同长度的字符串存在一个数组中,整体结构是个Map

search,没有点的时候,其实就是普通字符串的查找。
麻烦一点的地方是有点的时候,如果用非正则的法子,得判断点的位置,然后看看字符串。但是用正则的话,很方便,直接建立正则就好。

var WordDictionary = function() {
    this.words = {}

};

/** 
 * @param {string} word
 * @return {void}
 */
WordDictionary.prototype.addWord = function(word) {
    const len = word.length
    // 没有键的话,创建
    this.words[len] || (this.words[len] = [])
    // 存储到对应的键里
    this.words[len].push(word);
};

/** 
 * @param {string} word
 * @return {boolean}
 */
WordDictionary.prototype.search = function(word) {
    const len = word.length
    // 键对应的词表
    const list = this.words[len]
    // 没有词表,直接false
    if(!list) return false
    const hasPoint = word.includes('.')
    // 没有点的话 就是看看有没有词
    if(!hasPoint) return list.includes(word)
    // 建立正则
    const reg = new RegExp(word)
    // 看看有么有匹配的词
    return list.some(item=>reg.test(item))

};

练习:字符串转化成数字

string4

定理:题目长,意味着题目简单,考验的是耐心~~

  • 根据第一条,第一步,去掉前面的空格
  • 根据第二条,第二步,判断有没有正负号,没有的话就是正的
  • 根据第三条,第三步,遇到非数字或者结尾,停止捕获
  • 根据第四条,第四步,将数字部分字符串转化为数字
  • 根据第五条,第五步,转化的数字是不是过界了,最大最小是有界限的

如果用非正则的法子,前面三步需要挨个处理,但是正则的话,可以一次性处理。

var myAtoi = function (s) {
  // \s是空格,可有可无;+-任意一个可有可无;后面的数字必须有,主要捕获的就是符号加数字
  const reg = /^\s{0,}([+-]{0,1}[0-9]{1,})/;
  // 这边捕获第一个就够了,用exec足够
  const match = reg.exec(s);
  // 没有捕获到就是null,返回0
  if (!match) return 0;
  // 捕获到的话,第二项是需要的数字字符串,减0是转化为数字类型
  const number = match[1] - 0;
  const min = -Math.pow(2, 31);
  const max = Math.pow(2, 31) - 1;
  // 边界值处理
  return number > max ? max : number < min ? min : number;
};

官方视频

引用