2016-01-19 3 views
2

Мне нужно написать RegEx для использования в моем javascript, чтобы я мог сопоставить набор из трех последовательных слов. Это три слова будут переменными, как «раньше», «ошибка», «после». Дело в том, что «ошибка» всегда существует, но поскольку это может быть якорь при начале или конце предложения, «до» или «после» может отсутствовать. Таким образом, чтобы проиллюстрировать:RegEX в Javascript для соответствия набору слов

Если before= "this" after = "that" error="fail"

В предложении: test = "this fail that, but fail is not part of the result but can be in the case it is like this, fail"

Результат будет:

this fail that 
this fail 

только 2 из них правильно вернуться, поскольку они имеют "ошибка" слово и по крайней мере одно из двух боковых слов. Они могут быть символами между словом, поскольку я не получаю знаки препинания.

Я пытаюсь узнать RegEx, но до сих пор я только смог извлечь слово об ошибке что-то вроде: new RegExp("\\b" + motErreur + "\\b", "gi");

И в попытке я сделал за три слова не кажется правильно работать:

pattern = @"(?:^\W*|(?<"+before+">\w+)\W+)" + error + @"(?:\W+(?<"+after+">\w+)|\W*$)"; 

Как шаблон, взятый из примера в C# в моем коде и нуждающийся в нем в Javascript, я не знаю, не то ли это то, что заставляет его потерпеть неудачу.

Как я могу сделать это с помощью простого RegEx? цель заключается в замене части предложения предложения (у меня уже есть функция, написанная для этого, я только с этим RegEx).

+0

Вы используете именованные группы захвата, они не поддерживаются JS. Вы ищете ['(?:^\ W * | (\ w +) \ W +) fail (?: \ W + (\ w +) \ \ W * $)'] (https://regex101.com/r/ pC3pL5/1), правильно? –

+0

@ WiktorStribiżew такой позор. Но это объясняет, почему это не сработало. В случае вашего RegEx, где место для до или после? Потому что без них я получу какой-то матч, которого я не хочу. – Slayner

ответ

1

Поскольку вы используете шаблон в JS, вам нужно использовать конструктор обозначения и использовать пронумерованные группы захвата, а не (?<name>....) названные из них:

var before= "this", after = "that", error="fail"; 
 

 
var re = RegExp("(?:^\\W*|(" + before.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ")\\W+)" + error.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "(?:\\W+(" + after.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ")|\\W*$)", "g"); 
 
var str = 'this fail that, but fail is not part of the result but can be in the case it is like this fail'; 
 
var m; 
 
while ((m = re.exec(str)) !== null) { 
 
    document.body.innerHTML += m[0] + "<br/>"; 
 
}

Примечание:

  • Поскольку вы строите шаблон динамически, вам нужно использовать constr uctor обозначения (RegExp(...))
  • В конструктора обозначениях \ должна быть удвоена
  • В key может содержать специальные регулярных выражений метасимволы они должны быть экранированы следует рассматривать в качестве литералов (я добавил .replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
  • контекстные слова в m[1] и m[2]. Проверьте, не являются ли они undefined перед использованием.
+1

Проблема с вашим ответом заключается в том, что неудача является оммитированной, и результат, подобный «но неудача», не должен восприниматься как хороший результат, потому что вокруг него нет побочных слов, а всего лишь два других слова. – Slayner

+0

Хорошо, 'fail' есть, просто отобразите' m [0] ', но я не получаю проблему с' but fail is'. Вы имеете в виду, что все контекстные слова заданы? Должны быть поставлены в качестве аргументов? Проверьте этот обновленный фрагмент. –

+0

Проверьте этот обновленный фрагмент. –

1

Если вы правильно поняли вопрос, попробуйте (this\s+fail\s+that|this\s+fail|fail\s+that).

+0

в моем случае они переменные, до, ошибка, после. Я собираюсь попробовать и посмотреть. Они могут иметь символы между словом, кстати – Slayner

+0

Это будет соответствовать 'fail that' в любом месте строки, тогда как в отсутствие' this' он должен совпадать только в начале строки, если я правильно понимаю. –

+0

Я не совсем понял вопрос. Если это так, используйте '(this \ W + fail \ W +, что \ this \ W + fail $ |^fail \ W + this)', если символы, за исключением A-Z, a-z, 0-9 или _, считаются символами. – Gnubie

1

Использование регулярных выражений и EXEC метод, чтобы найти каждый матч:

var rgx = new RegExp("(" + before + "\\\s*" + error + "\\\s*(" + after + ")*)", "g") 
var resultArray = rgx.exec(test); 

Согласующий элемент в resultArray является одним с индексом 1 (например, resultArray [1].). Вызов метода exec, в то время как resultArray не равен нулю, чтобы найти все соответствующие элементы.

Таким образом, вы могли бы написать функцию:

function getMatches(str) 
{ 
    var before= "this"; 
    var after = "that"; 
    var error = "fail"; 
    var array = new Array(); 
    var rgx = new RegExp("(" + before + "\\\s*" + error + "\\\s*(" + after + ")*)", "g") 
    var matches = rgx.exec(test); 
    while(matches != null) 
    { 
     array.push(matches[1]); 
     matches = rgx.exec(test); 
    } 

    return array; 
} 
+0

это не сработает для случая «this, fail», поскольку после якоря нет, потому что отказ - это конец предложения. – Slayner

+0

Это не будет работать, если 'before', или' after' или 'error' содержат специальные метасимволы регулярных выражений. Кроме того, '' \\ s' следует использовать, а не '\\\ s' в нотации конструктора. –

+0

Если вам нужны все знаки препинания, вы можете заменить _ \\\ s * _ на _ [\\\ s,.;:!?] * _ Кроме того, _3 slashed s_ работает правильно, а ваш _2 разрезан s_ не : попробуй. –

Смежные вопросы