Обнаружение несоответствующей строки

#java #regex

#java #регулярное выражение

Вопрос:

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

{FF, SF, FB, SB, пауза}

Итак, когда я анализирую строку (которая может быть любой комбинацией из приведенных выше), если она обнаруживает, например, «FfdsG», она должна выдать ошибку. Я предполагаю, что я могу использовать какое-то регулярное выражение для выполнения этого или серии ifs.

Редактировать….

Плохая ли моя реализация? Я преобразую строку во все более низкие значения, а затем сравниваю. Независимо от того, что я отправляю в качестве входных данных (FB или FB, FF или что-то еще), кажется, что его пометка все плохая…

     `public static String check(String modes) {
     String s = modes;
     String lower = s.toLowerCase();

       HashSet<String> legalVals = new HashSet<String>();

        legalVals.add("ff");
        legalVals.add("sf");
        legalVals.add("fb");
        legalVals.add("sb");
        legalVals.add("pause");

        String valToCheck = lower;

        if (legalVals.contains(valToCheck)) { //False
            String str = modes;
        } else {
            return "Bad value: "   modes;
        }

       return modes;
      }
  

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


В итоге получилось следующее.

       String[] words = {"ff", "sf", "fb", "sb", "pause"};
       List<String> validList = Arrays.asList(words); 
       String checkInput = lower;

       for (String value : checkInput.split( "," ))
       {    
        if( !validList.contains( value ) )
        {
            throw new Exception("Invalid mode specified: "   modes);
        }
       }
  

Комментарии:

1. не могли бы вы рассказать нам, что вы пробовали?

Ответ №1:

Вы можете сохранить свои допустимые значения HashSet , например, в an и использовать contains() метод для проверки наличия определенного значения в списке:

 HashSet<String> legalVals = new HashSet<String>();

legalVals.add("FF");
legalVals.add("SF");
//etc

String valToCheck = "FfdsG";

if (legalVals.contains(valToCheck)) { //False
  print "Value found: "   valToCheck;
} else {
  print "Bad value: "   valToCheck;
}
  

Комментарии:

1. Я бы использовал HashSet over ArrayList . Проверка будет выполняться намного быстрее contains , особенно для длинных списков допустимых значений.

2. Упс, забыл изменить в разделе кода. Спасибо, незнакомец в маске!

3. кажется, независимо от того, что я ввожу в качестве входных данных, оно всегда возвращается как «неверное значение».

Ответ №2:

 (?<=(^|,))(?!((FF|SF|FB|SB|Pause)(?=(,|$))))
  

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

 (?<=(?:^|,))(?!(?:(?:FF|SF|FB|SB|Pause)(?=(?:,|$))))([^,]*)
  

первая захваченная группа будет содержать ее.

Ответ №3:

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

 public class InputCleaner
{
    private final static List<String> allowedEntries = Arrays.asList( new String[] { "FF", "SF", "FB", "SB", "Pause" } );

    public static void main( String[] args ) throws Exception
    {
        String input = "FF,SF,FB,SB,FF,Pause";
        String input2 = "FF,SF,FB,SB,FfdsG,FF,Pause";

        validateInput( input );
        validateInput( input2 );
    }

    private static void validateInput( String input ) throws Exception
    {
        for (String value : input.split( "," ))
        {    
            if( !allowedEntries.contains( value ) )
            {
                throw new Exception( "Found a bad input value! "   value );
            }
        }

        System.out.println( "Input string clean:"   input );
    }
}
  

Комментарии:

1. Извините, но «генерирует исключение» — одна из самых отвратительных вещей, которые я видел.

Ответ №4:

Не уверен, чего вы хотите. Для приведенного ниже регулярного выражения matches() вернет true, если все строки являются хорошими, и false, если есть одна или несколько неверных строк. Это регулярное выражение допускает любое количество пробелов в начале или конце строк. Кроме того, несколько запятых игнорируются. Например, » FF , SF ,,,,,,,, Pause » является совпадением. Удалите » s *» из регулярного выражения, чтобы запретить пробелы.

 (s*(FF|FB|SF|SB|Pause)s*,*) 
  

Ознакомьтесь с этим онлайн-инструментом регулярных выражений

Ответ №5:

 inputString.matches("FF|SF|FB|SB|Pause")
  

предполагая, что вы уже разделили ввод строки, разделенной запятыми, и inputString является одним элементом в этом разделенном массиве.

Ответ №6:

Да, Java имеет прекрасную поддержку регулярных выражений, и достаточно просто использовать оператор «ИЛИ» в вашем регулярном выражении, чтобы делать то, что вы хотите сделать. Что-то вроде этого должно проиллюстрировать суть:

 package exp;

import java.io.Console;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexTestHarness {

  public static void main(String[] args){

    Pattern pattern = Pattern.compile("FF|SF|FB|SB|Pause");

    Matcher matcher =  pattern.matcher( "FfdsG" );

    if (matcher.matches()) {
        System.out.printf("I found the text "%s" starting at "  
           "index %d and ending at index %d.%n",
            matcher.group(), matcher.start(), matcher.end());
    }
    else {
        System.out.printf("No match found.%n");
    }
    
    
    matcher = 
        pattern.matcher( "FF" );
    
        if (matcher.matches()) {
            System.out.printf("I found the text "%s" starting at "  
               "index %d and ending at index %d.%n",
                matcher.group(), matcher.start(), matcher.end());
        }
        else {
            System.out.printf("No match found.%n");
        }       
    

    matcher = 
        pattern.matcher( "Pause" );
    
        if (matcher.matches()) {
            System.out.printf("I found the text "%s" starting at "  
               "index %d and ending at index %d.%n",
                matcher.group(), matcher.start(), matcher.end());
        }
        else {
            System.out.printf("No match found.%n");
        }           
    
}

}
  

Когда вы запустите это, вы получите этот вывод:

Совпадение не найдено.

Я нашел текст «FF», начинающийся с индекса 0 и заканчивающийся индексом 2.

Я нашел текст «Пауза», начинающийся с индекса 0 и заканчивающийся индексом 5.

Итак, просто возьмите строку, разделенную запятой, перебирайте записи и используйте средство сопоставления.

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

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