2016-10-31 2 views
1

У меня есть список слов, разделенных запятой. e-mail: list.join(' ');
Как удалить слово (переменное) используя RegEx и не оставляя места позади?RegEx оставляет нежелательное пространство за

вид Пример кода:

var testClasses = document.getElementsByTagName("div")[0].className; 
 
var classToRemove = "test3"; 
 

 
document.getElementsByTagName('p')[0].innerHTML = "Removing class ." + classToRemove + " from: <strong>" + testClasses + "</strong>"; 
 

 
var re = new RegExp(classToRemove + "\s?", "g"); 
 
testClasses = testClasses.replace(re, ""); 
 

 
// I ran into the same problem trying to be more specific 
 
// var re = new RegExp("(\S+\s?)*(" + classToRemove + "\s?)(\S+\s?)*", "g"); 
 
// testClasses = testClasses.replace(re, "$1$3"); 
 

 

 
document.getElementsByTagName('p')[1].innerHTML = "becomes: <strong>" + testClasses + "</strong>" + " // which looks great on the DOM."; 
 
console.log(testClasses); 
 
console.log(testClasses.split(' '));
<div class="test1 test2 test3 test4 test5"></div> 
 
<p></p> 
 
<p></p> 
 
<p>However, if you check console, the space is there. <br><strong>How do I remove this extra space?</strong> Without having to run a second replace.</p>

Ограничения:

  • Я знаю, что это может быть достигнуто шпагатом или манипуляции массива. Тем не менее, я пытаюсь понять RegEx.
  • Используйте только один регекс. Две замены кажутся уродливыми и ненужными.
  • Я не могу предположить, что всегда будет пустое место до/после данного слова.
+1

Для сопоставления пробелов вам нужно буквальное '\ s' в шаблоне. Вы определяете необязательную букву 's' с' \ s? 'В' new RegExp (classToRemove + "\ s?", "G"); '. Вы имели в виду 'new RegExp (classToRemove +" \\ s? "," G ");'? И, возможно, вам нужно окончательное решение: var re = new RegExp ("\\ s *" + classToRemove, "g"); '. ' "\\ с *"'. Обратите внимание, что ('\ s *') соответствует нулю или нескольким пробелам. –

+0

любое количество пробелов -> '\ s *' – vlaz

+0

@ WiktorStribiżew Что делать, если в списке только есть слово, которое я хочу удалить? Он вообще не будет иметь никаких пробелов, поэтому он должен быть необязательным. – warkentien2

ответ

2

Могу ли я вас заинтересовать в Element.classList? Этот API позволяет мутировать атрибут class с помощью удобных методов, таких как .add(), .remove() и .toggle(). Это намного превосходит скорость вашего собственного решения RegExp.


Если это не должно быть решение RegExp, можно попробовать Array.filter:

'alpha bravo charlie' 
    .split(' ') 
    .filter(function(token) { return token !== 'alpha' }) 
    .join(' '); 

Но давайте перейдем с решением вашей RegExp загадку. В строке "alpha bravo charlie" вы хотите удалить любой из трех токенов, не оставляя лишних пробелов до, после или между оставшимися жетонами. Это может быть сделано с помощью negative look-ahead assertion (x(?!y)):

function removeToken(text, token) { 
    var pattern = new RegExp('(\\s+(?!\\S+\\s+))?' + token + '\\s*'); 
    return text.replace(pattern, ''); 
} 

Отрицательного взгляд вперед утверждение (\s(?!\S+\s+))? будет включать в себя только пространство в передней части маркеров, если нет пространства после маркеров. Таким образом, вы избегаете удаления обоих пространств, если вы удаляете токен посередине.Выражение читает «захватить один или несколько символов пробела, если за ними не следует один или несколько непространственных символов, за которыми следуют один или несколько пробелов». «Непространственные символы» соответствуют вашему токену, без необходимости также вводить токен. Поскольку эти ведущие пространства не всегда существуют, группа захвата становится необязательной с помощью конечного ?.

Чтобы проверить этот код, мы можем выполнить все четыре случая:

var text = 'alpha bravo charlie'; 
var tests = { 
    // <token to remove>: <resulting string> 
    'alpha': 'bravo charlie', 
    'bravo': 'alpha charlie', 
    'charlie': 'alpha bravo', 
    'delta': 'alpha bravo charlie', 
}; 

Object.keys(tests).forEach(function(token) { 
    var expected = tests[token]; 
    var result = removeToken(text, token); 
    console.log('removed "' + token + '" got "' + result + '" which is', expected === result ? 'correct' : 'WRONG'); 
}); 

и что должен печатать

removed "alpha" got "bravo charlie" which is correct 
removed "bravo" got "alpha charlie" which is correct 
removed "charlie" got "alpha bravo" which is correct 
removed "delta" got "alpha bravo charlie" which is correct 

Если ожидать, что ваши лексемы содержат символы, которые имеют значение в RegExp, вам 'd хотите, чтобы escape them.

+0

Я столкнулся с этой проблемой, пытаясь получить решение .classList для IE9. Поэтому я попытался создать add/remove из .className. Негативный взгляд на будущее - это золотой рудник, спасибо! Теперь я могу также сделать '' (\\ s + (? = \\ S + $))? ' + токен + '\\ s *' 'позитивный прогноз. Благодарим вас за очень разъясняющий ответ! Кроме того, спасибо, указав «RegExp.escape» – warkentien2

1

Чтобы соответствовать пробельному вам нужен буквальному \s в шаблоне, это означает, что обратный слэш и s. Вы определили необязательную букву s с "\s?" в new RegExp(classToRemove + "\s?", "g"), потому что в строковом листе C требуется две обратные косые черты для определения буквальной обратной косой черты.

Применение

var re = new RegExp("\\s*" + classToRemove, "g"); 

Обратите внимание, что "\\s*" (\s*) соответствует нулю или более пробелов. Поскольку classToRemove не может содержать символы, отличные от слов, для него не требуется экранирование с помощью регулярных выражений, поэтому я не добавляю этот код для экранирования.

Если может быть только одно вхождение имени класса, удалите глобальный модификатор "g" и просто используйте var re = new RegExp("\\s*" + classToRemove).

+0

Я понятия не имел, что это внезапно превратилось в строку C (моим первым языком программирования был C). Отличное объяснение! Благодаря! – warkentien2

+1

* C string literal * - тип строки, который позволяет использовать escape-последовательности, такие как '\ n' для новой строки,' \ r' для возврата каретки и т. Д. Когда вы используете '/ \ s /', обратная косая черта не обрабатывается как escape-последовательность, это буквальная обратная косая черта + 's'. –

+0

Что делать, если я хочу удалить первый элемент из списка? Этот предшествующий '\\ s *' не помогает. – warkentien2

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