Проверьте строку на наличие нескольких регулярных выражений и скажите, какое из них совпало

Прежде всего, я знаю, что уже есть тысячи сообщений RegEx, к сожалению, мои навыки поиска в google/stackoverflow не помогли найти то, что я искал.

У меня есть связь с клиентом сервера. Клиент ожидает ввода пользователя. Затем он отправляет его на сервер, и сервер проверяет, является ли это допустимой командой.

Pattern lowercase = Pattern.compile("LOWERCASE.*");
Pattern  uppercase = Pattern.compile("UPPERCASE.*");
Pattern  reverse = Pattern.compile("REVERSE.*");
Pattern  bye = Pattern.compile("BYE");
Pattern  shutdown = Pattern.compile("SHUTDOWN");

Если он начинается с одной из этих команд, выполните определенное действие. У меня проблемы с созданием Matcher, который проверяет несколько шаблонов, а затем я хочу перейти к чему-то вроде

Matcher.matches(uppercase|reverse|bye|...) //Is this how I do it?
switch(inputString){
case(lowercase):  do something
case(reverse):    do something else
}

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

Спасибо.


person InDaPond    schedule 25.09.2016    source источник


Ответы (2)


Вы делаете это шаблон за шаблоном и используете if вместо switch:

if (lowercase.matcher(inputStr).find()) {
    ... // Do something
} else if (reverse.matcher(inputStr).find()) {
    ... // Do something else
} else {
    ...
}

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

Pattern all = Pattern.compile(
    "(?<lower>LOWERCASE.*)|(?<upper>UPPERCASE.*)|(?<reverse>REVERSE.*)|..."
);
Matcher m = all.matcher(inputStr);
if (m.find()) {
    String upper = m.group("upper");
    String lower = m.group("lower");
    String reverse = m.group("reverse");
    if (upper != null) {
        ... // Do something
    }
    if (lower != null) {
        ... // Do something
    }
    if (reverse != null) {
        ... // Do something
    }
}

Обратите внимание, что в приведенном выше коде используются именованные группы захвата (<upper>, <lower> и т. д.).

person Sergey Kalinichenko    schedule 25.09.2016
comment
Ах да, я чувствую, что это то, что я искал - использование вашего второго подхода быстрее? Я подумал, что лучше не использовать Pattern.matcher.(expression).find(), потому что он будет компилироваться снова и снова и снова... в то время как второй подход просто компилирует его один раз. Правильно ли я понимаю это? Я еще новичок в программировании. - person InDaPond; 25.09.2016
comment
@InDaPond Это не так уж плохо, потому что каждый шаблон будет скомпилирован только один раз, а именно, когда вы вызываете compile(). Однако будет создано несколько экземпляров Matcher, что может быть неоптимальным. Несмотря на все это, вы должны выбрать подход, который лучше читается для вас (и, возможно, для людей, которые будут просматривать/обслуживать ваш код). Скорость - далекое второе место, потому что большая часть времени, проведенного в вашей системе, будет передавать данные на сервер и обратно. - person Sergey Kalinichenko; 25.09.2016
comment
Я пытался связаться с вами через чат, но понятия не имел, как это сделать. У меня есть дополнительный вопрос, возможно, вы тоже захотите посетить меня там: stackoverflow.com/questions/39734233/ Спасибо! - person InDaPond; 28.09.2016
comment
У меня до сих пор нет действительного ответа на это. Может глянем? @dasblinkenlight stackoverflow.com/questions/39756825/ - person InDaPond; 29.09.2016

Я бы сделал это так, используя Map с сопоставлением шаблонов с такими объектами, как Runnable, которые затем вызываются для выполнения кода. В качестве альтернативы вы можете сопоставить строки, а затем иметь оператор switch для этих укусов для выполнения вашего кода.

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

person Leon    schedule 25.09.2016