Разделение регулярных выражений приводит к дополнительному пространству, используя \\ s, но не избавляясь от него - PullRequest
1 голос
/ 01 августа 2020

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

import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.io.*;

public class StringLetters {

    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] temp = br.readLine().split("\\s*(\\{|,|\\}|\\s)\\s*");

            for (int i = 0; i < temp.length; i++) {
                System.out.println("temp[" + i + "] ===>" + temp[i]);
            }

            Set<String> set = new HashSet<>();
            for (String a : temp) {
                set.add(a);
            }

            System.out.println(set.size());
        } catch (IOException ioe) {

        }
    }
}

И когда я передаю {a, b, c}, это как вход

$ java StringLetters

  {a, b, c}

 temp[0] ===>
 temp[1] ===>a
 temp[2] ===>b
 temp[3] ===>c
 4

Другие входы могут быть {}, {s, h, a, n , o, n, o}, {h, e, a, l, h, t} ... et c

Итак, когда я делаю

   $ java StringLetters
    {}
    0

, правильно, для пустой строки я должен получить это 0.

Пустая строка в 0-м месте временного массива - это не то, что я хочу, чтобы избавиться от этого, я использую \ s внутри '(\ {|, | \} | \ s) ', но это мне здесь не помогает !!

Ответы [ 3 ]

2 голосов
/ 01 августа 2020

Если вам нужны только отдельные алфавиты из входных данных, я бы использовал go с другим подходом, чем разделение.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) throws ParseException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        Pattern pattern = Pattern.compile("\\p{Alpha}");
        Matcher matcher = pattern.matcher(br.readLine());

        Set<String> set = new HashSet<>();

        while (matcher.find()) {
            System.out.println(matcher.group());
            set.add(matcher.group());
        }

        System.out.println(set.size());
    }
}

Пробный прогон:

{a, b, c}
a
b
c
3

Другой прогон образца:

{}
0

Примечание: \p{Alpha} обозначает один алфавит и может быть заменен на [A-Za-Z]. Узнайте больше об этих шаблонах здесь . Вы также хотели бы проверить Java учебник по регулярным выражениям .

Если вы хотите придерживаться своего собственного способа сделать это (например, разделить строку), вы можете сделать это следующим образом:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) throws ParseException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] temp = br.readLine().split("\\s*(\\{|,|\\}|\\s)\\s*");

        for (int i = 1; i < temp.length; i++) {// Start with index 1
            System.out.println("temp[" + i + "] ===>" + temp[i]);
        }

        Set<String> set = new HashSet<>();
        for (String a : temp) {
            if (!a.isBlank() && !a.isEmpty()) {// Check if the string is not empty or blank
                set.add(a);
            }
        }

        System.out.println(set.size());
    }
}

Пример выполнения:

{a, b, c}
temp[1] ===>a
temp[2] ===>b
temp[3] ===>c
3

Я добавил в код комментарии, чтобы вам было легче заметить изменения. Причина, по которой требуются эти изменения: String#split возвращает массив с минимальным размером 1, например, System.out.println("Hello".split("$").length) напечатает 1.

1 голос
/ 01 августа 2020

Регулярное выражение видит {в качестве первого разделителя, что дает вам пустую строку. Самый простой способ - отфильтровать массив при создании Set:

        Set<String> set = new HashSet<>(); 
        for(String a : temp){
            if (a != null && !a.isEmpty())
               set.add(a);
        }
0 голосов
/ 01 августа 2020

Без вызова разделения указанная выше задача может быть выполнена следующим образом: -

import java.util.Set;
import java.util.HashSet;
import java.io.*;

public class StringLetters {
  
    public static void main(String[] args){
      
        try{
           
          BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
          String str = br.readLine();
          Set<Character> set = new HashSet<>();
          for(int i = 0; i < str.length(); i++){
            
              if(str.charAt(i) != '{' && str.charAt(i) != '}' && str.charAt(i) != ' ' && str.charAt(i) != ','){
                 
                 set.add(str.charAt(i));

              }
          }

          System.out.println(set.size());
        
        }catch(IOException ioe){
          ioe.printStackTrace();
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...