Как разбить текст по номерам и группам слов - PullRequest
0 голосов
/ 14 июня 2019

Предполагая, что у меня есть строка, содержащая - некоторая строка, разделенная запятыми, - и текст

  my_string =  "2 Marine Cargo       14,642 10,528       16,016 more text 8,609 argA 2,106 argB"

Я хотел бы извлечь их в массив, который разделен на «Числа» и «группу слов»

 resultArray = {"2", "Marine Cargo", "14,642", "10,528", "16,016",
                "more text", "8,609", "argA", "2,106", "argB"};

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

примечание 1: «Морской груз» и «дополнительный текст» не разделяются на разные строки, поскольку ониявляются группой слов без цифр, разделяющих их.в то время как argA и argB разделены, потому что между ними есть число.

Ответы [ 4 ]

3 голосов
/ 14 июня 2019

вы можете попробовать разделить, используя это регулярное выражение

([\d,]+|[a-zA-Z]+ *[a-zA-Z]*) //note the spacing between + and *.
  • [0-9,] + // будет искать одну или несколько цифр и запятых
  • [a-zA-Z] + [a-zA-Z] // будет искать слово, за которым следует пробел (если есть), за которым следует другое слово (если есть).

    String regEx = "[0-9,]+|[a-zA-Z]+ *[a-zA-Z]*";
    

вы используете их вот так

public static void main(String args[]) {

  String input = new String("2 Marine Cargo       14,642 10,528       16,016 more text 8,609 argA 2,106 argB");
  System.out.println("Return Value :" );      

  Pattern pattern = Pattern.compile("[0-9,]+|[a-zA-Z]+ *[a-zA-Z]*");

  ArrayList<String> result = new ArrayList<String>();
  Matcher m = pattern.matcher(input);
  while (m.find()) { 
         System.out.println(">"+m.group(0)+"<");  
         result.add(m.group(0));

   }
}

Ниже приведен вывод, а также подробное объяснение RegEx, которое автоматически генерируется из https://regex101.com

enter image description here

1st Alternative [0-9,]+
Match a single character present in the list below [0-9,]+
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
0-9 a single character in the range between 0 (index 48) and 9 (index 57) (case sensitive)
, matches the character , literally (case sensitive)


2nd Alternative [a-zA-Z]+ *[a-zA-Z]*
Match a single character present in the list below [a-zA-Z]+
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
a-z a single character in the range between a (index 97) and z (index 122) (case sensitive)
A-Z a single character in the range between A (index 65) and Z (index 90) (case sensitive)
 * matches the character   literally (case sensitive)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Match a single character present in the list below [a-zA-Z]*
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
a-z a single character in the range between a (index 97) and z (index 122) (case sensitive)
A-Z a single character in the range between A (index 65) and Z (index 90) (case sensitive)
1 голос
/ 14 июня 2019

Мне нравится Angel Koh решение и хочу добавить к нему. Его решение будет соответствовать, только если числовая часть состоит из одной или двух частей.

Если вы также хотите захватить части, состоящие из трех или более частей, вам нужно немного изменить регулярное выражение на: ([\d,]+|[a-zA-Z]+(?: *[a-zA-Z])*)
Группа без захвата (?: *[a-zA-Z]) повторяется бесконечно много раз, если необходимо, и захватывает все чистые числовые части.

1 голос
/ 14 июня 2019

Вы могли бы сделать что-то вроде этого:

    List<String> strings = new ArrayList<>();
    String prev = null;
    for (String w: my_string.split("\\s+")) {
        if (w.matches("\\d+(?:,\\d+)?")) {
            if (prev != null) {
                strings.add(prev);
                prev = null;
            }
            strings.add(w);
        } else if (prev == null) {
            prev = w;
        } else {
            prev += " " + w;
        }
    }
    if (prev != null) {
        strings.add(prev);
    }
1 голос
/ 14 июня 2019

Если пробелы - ваша проблема. String # split принимает в качестве параметра регулярное выражение. Тогда вы можете сделать это: my_list = Arrays.asList(my_string.split("\s?"));

Но это не решит всех проблем, подобных тем, которые упоминаются в комментариях.

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