2013-10-10 3 views
2

Предположим, у меня есть строка, такая как 'a b xy c pq', и мне нужно написать регулярное выражение, чтобы метод match() возвращал массив liek: ['a','b','xy','c','pq'].Необходимое регулярное выражение Javascript

Давайте рассмотрим несколько примеров:

>>> 'x y z '.match(/\w{1,3}\s+/g) 
['x ', 'y ', 'z '] 

>>> 'x y z '.match(/(\w{1,3})\s+/g) 
['x ', 'y ', 'z '] 

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

Как вы думаете, я могу улучшить это регулярное выражение, чтобы получить то, что я хочу?

Обратите внимание, что я не хочу использовать exec(), потому что его нужно запускать несколько раз, чтобы получить все совпадения.

отметить также, что эта проблема может быть легко решена с split()

>>> 'x y z'.split(/\s/) 
['x', 'y', 'z'] 

>>> "a b xy c pq".split(/\s/) 
['a','b','xy','c','pq'] 

Но, мне нужно также проверить строку. В каждом матче должно быть не более трех символов, и каждое совпадение должно быть буквенно-цифровым словом без специальных символов. Следовательно, я не могу использовать split(), потому что в этом случае мне пришлось бы проверять каждое соответствие отдельно. Я хочу сделать все это с помощью одного регулярного выражения.

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

+0

Что случилось с тем, 'exec' должен быть запущен несколько раз? Разумеется, вы можете переместить его в _function_, если хотите сохранить эту конкретную область вашего кода чистой/сделать ее более читаемой. –

+0

Множественные вызовы exec уменьшают производительность. И не забывайте, что вам нужно проверять 'lastIndex' на каждой итерации, что еще больше ухудшает скорость. – treecoder

+0

Когда 'exec' продолжается, он правдивый, когда он заканчивается, он дает« null », поэтому, когда я его использую, я просто делаю' while (foo = re.exec (bar))/*, затем используйте */foo; ', no 'lastIndex' проверка –

ответ

2

При добавлении \s+ шаблон соответствует пробелам.

Удалить \s+:

'x y z '.match(/\w{1,3}/g) 
// => ["x", "y", "z"] 

Использование \b, вы можете соответствовать на границе слова.

'x y z '.match(/\b\w{1,3}\b/g) 
// => ["x", "y", "z"] 
'x yyyyyyyyyy z '.match(/\b\w{1,3}\b/g) 
// => ["x", "z"] 
+0

Но тогда это будет соответствовать этому неверно:' 'xy abcdefgh '.match (/ \ w {1,3}/g', что приводит к' [' x ',' y ',' abc ' , 'def', 'gh'] ' – treecoder

+0

@good_computer, см. второй код, который использует' \ b'. – falsetru

+0

Да, со словом границы он удалит '' abcdefgh'' из результата, но мне нужно, чтобы он сделал недействительным целую строку, потому что я хочу только совпадения с 3 символами макс, поэтому он должен возвращать значение null, а не массив со совпадениями в этом случае. – treecoder

0

Регулярное выражение: /(?!.*?\w{4,}.*?)\b\w{1,3}\b/g, кажется, работает для меня

var tests = ['x y z ','a b xy c pq','x y abcdefgh ','abc d rar','rawr']; 

for(var i=0,c=tests.length;i<c;i++) 
{ 
    var str = tests[i]; 
    console.log(str.match(/(?!.*?\w{4,}.*?)\b\w{1,3}\b/g)); 
} 

/* 
Results: 

["x", "y", "z"] 
["a", "b", "xy", "c", "pq"] 
null 
["abc", "d", "rar"] 
null 
*/ 
+0

К сожалению, это не сработает. Например: '' 123 123 1234 '-> null', что верно. Но, '1231234 123 '-> [' 123 ']', который также должен вернуть значение null. ''1234 123 123' -> ['123', '123']', который также должен вернуть значение null. Он должен возвращать массив совпадений ТОЛЬКО, когда все пробелы, разделенные пробелами, имеют 3 символа или меньше и должны возвращать null в противном случае. – treecoder

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