Помогите с регулярным выражением включить и исключить

Мне нужна помощь с регулярным выражением.

Я пытаюсь создать выражение, которое будет включать определенные строки и исключать определенные строки.

Например:

Я хотел бы включить любой URL-адрес, содержащий мобильность http://www.something.com/mobility/

Однако я хотел бы исключить любой URL-адрес, содержащий магазин http://www.something.com/store/mobility/

К вашему сведению, у меня есть много ключевых слов, которые я использую для включения. В настоящее время я включаю вот так /mobility|enterprise|products/i, однако не могу исключить ссылки, содержащие другие ключевые слова.

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

_t


person Tom    schedule 15.03.2011    source источник
comment
Вы должны указать язык, из которого вы используете регулярные выражения.   -  person xanatos    schedule 15.03.2011


Ответы (3)


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

function validate(str) {
    var required = /\b(mobility|enterprise|products)\b/i;
    var blocked = /\b(store|foo|bar)\b/i;

    return required.test(str) && !blocked.test(str);
}

Если вы действительно хотите сделать это по одному шаблону, попробуйте что-то вроде этого:

/(?=.*\b(mobility|enterprise|products)\b)(?!.*\b(store|foo|bar)\b)(.+)/i

i в конце означает без учета регистра, поэтому используйте эквивалент вашего языка, если вы не используете JavaScript.

Все, что было сказано, основываясь на вашем описании проблемы, я думаю, что вы ДЕЙСТВИТЕЛЬНО хотите для этого манипуляции со строками. Вот пример, опять же с использованием JS:

function validate(str) {
    var required = ['mobility','enterprise','products'];
    var blocked = ['store','foo','bar'];
    var lowercaseStr = str.toLowerCase(); //or just use str if you want case sensitivity

    for (var i = 0; i < required.length; i++) {
        if (lowercaseStr.indexOf(required[i]) === -1) {
            return false;
        }
    }

    for (var j = 0; j < blocked.length; j++) {
        if (lowercaseStr.indexOf(blocked[j]) !== -1) {
            return false;
        }
    }
}
person Justin Morgan    schedule 15.03.2011
comment
Спасибо за помощь, но мне действительно нужно это использование в Google Analytics для создания фильтра, который не использует язык для манипуляций, по крайней мере, до которого я могу добраться. - person Tom; 15.03.2011
comment
Ницца. Кажется, самая последняя версия вашего единственного выражения делает свое дело. Большое спасибо за Вашу помощь. - person Tom; 15.03.2011
comment
@ Том - рад помочь. Удачи. - person Justin Morgan; 15.03.2011

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

^(?=.*(?:inc1|inc2|...))

Чтобы не совпадать со строкой, в которой есть слово из списка стоп-слов, вы можете использовать отрицательный просмотр вперед как:

^(?!.*(?:ex1|ex2|...))

Вы можете объединить два вышеуказанных требования в одном регулярном выражении как:

^(?=.*(?:inc1|inc2|...))(?!.*(?:ex1|ex2|...))REGEX_TO_MATCH_URL$

Рубулярная ссылка

person codaddict    schedule 15.03.2011

Сделать два регулярных выражения, одно для хорошего и одно для плохого, и проверить оба? (сначала плохое, потом хорошее). Вы можете сделать это с помощью одного регулярного выражения, но KISS всегда является хорошим правилом ( http://en.wikipedia.org/wiki/KISS_principle )

Я добавлю, что вам нужно учитывать принцип "задницы"... .*ass соответствует ambassador и cassette, так что вы, вероятно, захотите иметь разделитель ([./\\]) до и после каждого слова. Фильтры непристойности: Плохая идея или невероятно плохая идея?

person xanatos    schedule 15.03.2011