2009-02-23 3 views
2

Я пытался сделать регулярное выражение для кого-то еще, когда столкнулся с этой проблемой. Требовалось, чтобы регулярное выражение возвращало результаты из набора строк, который имеет, скажем, «яблоко» в нем. Например, рассмотрим следующие строки:Javascript regex

"I have an apple" "You have two Apples" "I give you one more orange"

Результирующий набор должен иметь первые две строки.

Регулярное выражение (а) Я попытался это:

/[aA]pple/ и /[^a-zA-Z0-9][aA]pple/

Проблема с первым является то, что такие слова, как «aapple», «bapple», и т.д. (в порядке, так что они не имеют смысла , но все же ...) положительный результат теста, а проблема со вторым заключается в том, что, когда строка фактически начинается со слова «яблоко», «яблоки и апельсины», например, он испытывает отрицательный результат. Может ли кто-нибудь объяснить, почему второе регулярное выражение ведет себя так и каково правильное регулярное выражение?

ответ

8
/(^.*?\bapples?\b.*$)/i 

Edit: выше будет соответствовать всей строки, содержащие слово «яблоки», который я думал, что вы просили. Если вы просто пытаетесь увидеть, содержит ли строка это слово, будет работать следующее.

/\bapples?\b/i 

Регулярное выражение (а) Я попытался это:

/[aA]pple/ and /[^a-zA-Z0-9][aA]pple/

Первый раз проверяет наличие следующих символов, в следующем порядке: яблоко, независимо от того, контекст, в котором они используются. Символ \ b или слово-граница соответствует любому месту, где встречаются символ неслов и символ слова, ala \W\w.

Второй пытается сопоставить другие символы перед появлением a-p-p-l-e и по существу совпадает с первым, за исключением того, что требует других символов перед ним.

Тот, на который я ответил, работает следующим образом. Начиная с начала строки, любые символы (если они существуют) не с жадностью, пока не встретит границу слова. Если строка начинается с apple, начало строки является границей слов, поэтому она по-прежнему совпадает. Затем он соответствует буквам a-p-p-l-e и s, если он существует, за которым следует еще одна граница слова. Затем он соответствует всем символам в конце строки./I в конце означает, что он не чувствителен к регистру, так что «Apple», «APPLE» и «apple» действительны.

Если у вас есть время, я настоятельно рекомендую пройти через учебник по адресу http://regular-expressions.info. Это действительно углубленно и говорит о том, как двигатели регулярных выражений соответствуют разным выражениям, это помогло мне тонну.

+0

опередил меня :) – annakata

+0

Он потерпит неудачу на Appleseed, как Джонни. Я сомневаюсь, что это очень важно. – gpojd

+0

Пожалуйста, не используйте «^. *?» И «. *? $»! – Gumbo

0
/\bapple/i 

\ b является word boundary.

Чтобы объяснить, почему ваши попытки не работают, первый не проверяет, является ли это началом слова, поэтому он может иметь что-то перед этим. Второе регулярное выражение, которое вы указали, говорит, что что-то должно быть перед словом «яблоко», но оно не может быть буквенно-цифровым.

0

Ваше второе регулярное выражение требует символа nonalphanumeric перед первым a в яблоке. «Яблоко» этого не удовлетворяет. Как отмечают другие, «\ b» соответствует не символу, а границе слова.

3

Чтобы построить на @ tj111, причиной неудачи вашего второго регулярного выражения является то, что [^a-zA-Z0-9] требует, чтобы символ соответствовал; то есть в этом месте есть какой-то символ, и его значение не содержится в наборе [a-zA-Z0-9]. Такие маркеры, как \b, называются «утверждениями с нулевой шириной». \b, в частности, соответствует границам между символами или в начале или конце строки. Поскольку он не соответствует ни одному символу, его «ширина» равна нулю.

В сумме [^a-zA-Z0-9] требует наличия символа, который не принимает определенное значение, а \b требует наличия границы.

Редактировать: @ tj111 добавил большую часть этого ответа. Я слишком поздно, опять-таки :)

+0

все еще стоит +1 для обсуждения утверждений «нулевой ширины». – tj111

+0

gotta love regular-expressions.info :) – kyle

1

Это работает для apple и apples и его регистронезависимых написаний:

var strings = ["I have an apple", "You have two Apples", "I give you one more orange"]; 
var result = []; 
var pattern = /\bapples?\b/i; 
for (var i=0; i<strings.length; i++) { 
    if (pattern.test(strings[i])) { 
     result.push(strings[i]); 
    } 
}