Как искать подстроку в строке с помощью регулярных выражений в JavaScript? - PullRequest
2 голосов
/ 24 сентября 2019

У меня есть строка, подобная приведенной ниже

Hello there how are you?

Я хочу найти в строке подстроку 'there how'.Поэтому я бы сделал что-то вроде этого

var str = "Hello there how are you?"; 
var term = "there how"
var res = str.match("\\s" + term + "\\s"); //  # /s is used to ensure the match should be an independent phrase

Но теперь проблема в том, что если я получу вариант строки, то совпадение не произойдет.Например, для таких строк:

Если между словами есть большой интервал

Hello there         how are you?

Если некоторые буквы пишутся с заглавной буквы

Hello There How are you?

Что я хочусделать, чтобы убедиться, что пока подстрока 'there how' присутствует в строке как отдельная фраза (не как Hellothere how are you? или Hello there howare you? и т. д.), я смогу найти совпадение.

Какможно ли достичь цели?

Благодаря @Wiktor Stribiżew он предложил это решение ниже

var ss = ["Hello there how are you?", "Hello there         how are you?", "Hello There How are you?"];
var term = "there how";
var rx = new RegExp("(?<!\\S)" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");
for (var i=0; i<ss.length; i++) {
    var m = ss[i].match(rx) || "";
    console.log(m[0]);
}

Хотя это работает в онлайн-компиляторе nodejs, например, repl https://repl.it/repls/AwkwardSpitefulAnimatronics, оно выиграло 'не работает в обычном javascript.

Я получаю эту ошибку ниже в javascript для этой строки

var rx = new RegExp("(?<!\\S)" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");    

SyntaxError: invalid regexp group

Как мне достичь своей цели?

Ответы [ 4 ]

1 голос
/ 24 сентября 2019

Ниже приведен пример использования термина как части регулярного выражения.Установочные переменные взяты из ответа анубхавы .

// setup variables from other answers
var ss = ["Hello there how are you?", "Hello there         how are you?", "Hello There How are you?"];
var term = "there how";

// if you want to use the term in the regex, replace the space(s) with \\s+ (1 or more spaces)
function replaceSpaces(s) {
  return s.replace(/ /g, "\\s+")
}

// create regex
var pattern = new RegExp(`\\s${replaceSpaces(term)}\\s`)

// lowercase before comparing to ignore case
// if the regex needs to be case insensitive too, lowercase the output of replaceSpaces(term) as well
console.log(ss.map(s => pattern.test(s.toLowerCase())))
1 голос
/ 24 сентября 2019

Многие браузеры по-прежнему не поддерживают просмотр, поэтому вы получаете эту ошибку.Вы можете использовать этот подход:

var ss = ["Hello    there how are you?", "Hello there         how are you?", "Hello, There How are you?"];
var term = "there how";

var rx = new RegExp("(?:^|\\s)(" + term.replace(/ +/g, "\\s+") + ")(?!\\S)", "gi");

var m;
for (var i=0; i<ss.length; i++) {
    while(m = rx.exec(ss[i])) {
      console.log('Start:', m.index, 'End:', rx.lastIndex, m[1]);
    }
}
  • (?:^|\\s) - это группа без захвата, которая соответствует началу строки или пробелу в левой части термина.
  • Также обратите внимание на использованиегруппы захвата, чтобы получить желаемую подстроку из заданного ввода.
1 голос
/ 24 сентября 2019

В зависимости от того, как вы хотите, чтобы ваши результаты возвращались, вы можете решить проблему одним из двух способов.Если вы хотите, чтобы искомый термин возвращался в точности так, как он отображается во входных данных, вы можете сделать регулярное выражение более общим (вариант 1).Однако, если вы хотите, чтобы результаты возвращались в соответствии с форматированием поискового запроса, вы можете сначала очистить входные данные, чтобы удалить лишние пробелы и заглавные буквы.

Как упомянул Тим выше, разрыв слова \b должен бытьдостаточно, чтобы определить, что фраза не зависит от других слов в входных данных.

var ss = ["Hello there how are you?", "Hello there         how are you?", "Hello There How are you?", "Hello There Howare you?"]



function buildRgx(term){
  let spaceFix = term.split(' ').join('\\s+')
  return new RegExp('\\b' + spaceFix + '\\b', 'i')
}

var generalizedSearchTerm = buildRgx("there how")

ss.forEach(str => {
  let result = generalizedSearchTerm.exec(str)
  if(result){
    strmatch = result[0],
    indexstart = result.index,
    indexend = indexstart + strmatch.length
  
    console.log(strmatch, indexstart, indexend)
  } else {
    console.log('no match found')
  }
})


//OR sanitize the input first
console.log('OR')

function sanitizeStr(str){ return str.toLowerCase().replace(/\s+/g, ' ') }

var simpleSearchTerm = new RegExp('\\b' + "there how" + '\\b')

ss.forEach(str => {
  let sanitizedString = sanitizeStr(str)
  console.log(simpleSearchTerm.exec(sanitizedString))
})
1 голос
/ 24 сентября 2019

Часть (?<!\\S) строки регулярного выражения - это то, что вызывает ошибку, и это происходит в вашей обычной версии JavaScript, которая не поддерживает просмотр за плечами, даже просмотр за фиксированной шириной.Один из обходных путей - просто использовать вместо этого границу слова:

var rx = new RegExp("\\b" + term.replace(/ /g, "\\s+") + "(?!\\S)", "i");

Предполагая, что term начинается и заканчивается символами слова, \b должно быть достаточно, чтобы охватить желаемое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...