正则表达式匹配带或不带撇号的字符串

时间:2019-01-02 07:55:34

标签: javascript regex

我通过使用用户输入的查询来突出显示搜索结果中的单词。一些结果包含诸如撇号之类的符号,无论是否输入撇号,我都希望突出显示。所以,如果我有这个搜索结果

帕特里克·奥哈根

然后用户输入

奥哈根

Ohagan

它应该与突出显示的部分匹配:Patrick O'Hagan

我想到的一种实现此目的的方法是通过在用户输入的每个字符后插入一个不需要的撇号来构建正则表达式,因此查询ohagan会转换为该正则表达式:

/(o[']?h[']?a[']?g[']?a[']?n[']?)/gi

这可行,但是必须有更好的方法吗?

编辑: 我之前提供的示例尚不清楚,因此我将仅提供一个示例代码,该代码应显示我想要实现的目标:

    var resultText = 'Patrick O\'Hagan';
    var query1 = 'o\'hagan';
    var query2 = 'ohagan';

    var regex1 = this.buildRegex(query1);
    var regex2 = this.buildRegex(query2);

    var highlightedText1 = resultText.replace(regex1, x => `<b>${x}</b>`);
    var highlightedText2 = resultText.replace(regex2, x => `<b>${x}</b>`);

    console.log(highlightedText1); //prints: Patrick <b>O'Hagan</b>;
    console.log(highlightedText2); //prints: Patrick <b>O'Hagan</b>;

我要寻找的是buildRegex函数,该函数将构造一个正则表达式,该表达式与resultText中的查询匹配,但会忽略撇号。

1 个答案:

答案 0 :(得分:0)

每个字符

Alternation |

字符OR或字符后跟撇号

  1. split()关键字(例如obrien)转换为字符数组:

    var searchLetters = keyword.split('')
    
    // ['o','b','r','i','e','n']
    
  2. map()将每个字符转换为正则表达式字符串,该字符串将接受${文字匹配}| ${文字匹配{{ 1}},后接单引号:}或单引号:[’

    ']
  3. 接下来,join()将新的正则表达式字符串数组转换为单个正则表达式字符串,并在RegExp Object中使用它:

    var regexStrings = searchLetters.map(function(character) {
      return `(${character}|${character}['’])`;
    });
    
    // [`(${o}|${o}['’])`,`(${b}|${b}['’])`,`(${r}|${r}['’])`...]
    
  4. 该RegExp对象将用于用<mark> tag包装所有匹配项:

    var singleRegex = regexStrings.join('');
    var regexObject = new RegExp(`(${singleRegex})`, `gi`);
    

演示

var hits = targetContent.innerHTML.replace(regexObject, `<mark>$1</mark>`);
document.getElementById('search').addEventListener('change', function(e) {
  highlight(this.value, '#content');
});

function highlight(keyword, selector) {
  var node = document.querySelector(selector);
  var html = node.innerHTML;
  var clean = html.replace(/(<mark>|<\/mark>)/, '');
  var escaped = keyword.replace(/[.*+?^${}()|[\]\\]/gi, '\\$&');
  var letters = escaped.split('').map(function(letter) {
    return `(${letter}|${letter}['’])`;
  });
  var string = letters.join('');
  var regex = new RegExp(`(${string})`, `gi`);
  var hits = clean.replace(regex, `<mark>$1</mark>`);
  node.innerHTML = hits;
}