2017-02-13 6 views
1

У меня эти строки;Разделить строку в массиве

wordsExpanded="test | is | [(thirty four) {<number_type_0 words>}(3 4) {<number_type_0 digits>}] | test | [(three) {<number_type_1 words>}(3) {<number_type_1 digits>}] | [(one) {<number_type_2 words>}(1) {<number_type_2 digits>}]" 

interpretation="{<number_type_2 digits> <number_type_1 digits> <number_type_0 words>}" 

что мне нужно, поскольку вывод такой строки;

finalOutput="test | is | thirty four | test | 3 | 1 " 

В основном строка интерпретации содержит информацию, необходимую для определения того, какая группа была использована. Для первого, мы использовали и, следовательно, собственно строка «(тридцать четыре)», а не «(3 4)» Второй будет «(3)», а затем «(1)»

Вот мой код до сих пор;

package com.test.prova; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Prova { 

    public static void main(String[] args) { 
     String nlInterpretation="{<number_type_2 digits> <number_type_1 digits> <number_type_0 words>}"; 
     String inputText="this is 34 test 3 1"; 
     String grammar="test is [(thirty four) {<number_type_0 words>}(3 4) {<number_type_0 digits>}] test [(three) {<number_type_1 words>}(3) {<number_type_1 digits>}] [(one) {<number_type_2 words>}(1) {<number_type_2 digits>}]"; 

     List<String> matchList = new ArrayList<String>(); 
     Pattern regex = Pattern.compile("[^\\s\"'\\[]+|\\[([^\\]]*)\\]|'([^']*)'"); 
     Matcher regexMatcher = regex.matcher(grammar); 
     while (regexMatcher.find()) { 
      if (regexMatcher.group(1) != null) { 
       matchList.add(regexMatcher.group(1)); 
      } else if (regexMatcher.group(2) != null) { 
       matchList.add(regexMatcher.group(2)); 
      } else { 
       matchList.add(regexMatcher.group()); 
      } 
     } 

     String[] xx = matchList.toArray(new String[0]); 
     String[] yy = inputText.split(" "); 

     matchList = new ArrayList<String>(); 
     regex = Pattern.compile("[^<]+|<([^>]*)>"); 
     regexMatcher = regex.matcher(nlInterpretation); 
     while (regexMatcher.find()) { 
      if (regexMatcher.group(1) != null) { 
       matchList.add(regexMatcher.group(1)); 
      } 
     } 
     String[] zz = matchList.toArray(new String[0]); 
     System.out.println(String.join(" | ",zz)); 

     for (int i=0; i<xx.length; i++) { 
      if (xx[i].contains("number_type_")) { 
       matchList = new ArrayList<String>(); 
       regex = Pattern.compile("[^\\(]+|<([^\\)]*)>.*[^<]+|<([^>]*)>"); 
       regexMatcher = regex.matcher(xx[i]); 
       while (regexMatcher.find()) { 
        if (regexMatcher.group(1) != null) { 
         matchList.add(regexMatcher.group(1)); 
        } else if (regexMatcher.group(2) != null) { 
         matchList.add(regexMatcher.group(2)); 
        } else { 
         matchList.add(regexMatcher.group()); 
        } 
       } 
       System.out.println(String.join(" | ",matchList.toArray(new String[0]))); 
      } 
      System.out.printf("%02d\t%s\t->%s\n", i, yy[i], xx[i]); 
     } 
    } 
} 

Выход, сгенерированный следующим образом;

number_type_2 digits | number_type_1 digits | number_type_0 words 
00 this ->test 
01 is ->is 
thirty four) {<number_type_0 words>} | 3 4) {<number_type_0 digits>} 
02 34 ->(thirty four) {<number_type_0 words>}(3 4) {<number_type_0 digits>} 
03 test ->test 
three) {<number_type_1 words>} | 3) {<number_type_1 digits>} 
04 3 ->(three) {<number_type_1 words>}(3) {<number_type_1 digits>} 
one) {<number_type_2 words>} | 1) {<number_type_2 digits>} 
05 1 ->(one) {<number_type_2 words>}(1) {<number_type_2 digits>} 

Что мне больше всего нравится;

number_type_2 digits | number_type_1 digits | number_type_0 words 
00 this ->test 
01 is  ->is 
02 34  ->thirty four 
03 test ->test 
04 3  ->3 
05 1  ->1 
+0

Могли вы показываете третий пример? – alayor

+0

очень неясно. Приведите пример –

+0

У меня нет ИДЕИ, что означает этот вопрос. Являются ли серые части действительными строками или являются ли они метасинтетическими переменными? –

ответ

0

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

Вот мой новый код;

public static String parseString(String grammar, String interoperation) { 
     if (grammar==null || interoperation == null || interoperation.equals("{}")) 
      return null; 

     List<String> matchList = new ArrayList<String>(); 
     Pattern regex = Pattern.compile("[^\\s\"'\\[]+|\\[([^\\]]*)\\]|'([^']*)'"); 
     Matcher regexMatcher = regex.matcher(grammar); 
     while (regexMatcher.find()) { 
      if (regexMatcher.group(1) != null) { 
       matchList.add(regexMatcher.group(1)); 
      } else if (regexMatcher.group(2) != null) { 
       matchList.add(regexMatcher.group(2)); 
      } else { 
       matchList.add(regexMatcher.group()); 
      } 
     } 

     String[] xx = matchList.toArray(new String[0]); 
     String wordsExpanded = String.join(" | ",xx); 

     interoperation= interoperation.replaceAll("\\{", "") 
             .replaceAll("\\}", ""); 

     Set<String> allInterOperations = Arrays.asList(interoperation.split(">")) 
      .stream() 
      .map(eachInterOperation -> { 
      eachInterOperation = eachInterOperation.trim(); 
      eachInterOperation = eachInterOperation + ">"; 
      return eachInterOperation; 
     }).collect(Collectors.toSet()); 

     String result = Arrays.asList(wordsExpanded.split("\\|")) 
      .stream() 
      .map(eachWordExpanded -> { 
       eachWordExpanded = eachWordExpanded.trim(); 
       eachWordExpanded = eachWordExpanded.replaceAll("\\{", ""); 
       eachWordExpanded = eachWordExpanded.replaceAll("\\}", ""); 

       for(String eachInterOperation : allInterOperations){ 
        if(eachWordExpanded.contains(eachInterOperation)){ 
         Pattern pattern = Pattern.compile("(\\(.*?\\))\\s*(<.*?>)"); 
         Matcher matcher = pattern.matcher(eachWordExpanded); 
         while (matcher.find()) { 
          if (matcher.group(2).equals(eachInterOperation)) 
           eachWordExpanded = matcher.group(1).replaceAll("[\\(\\)]", "").trim(); 
         } 
        }else{ 
         continue; 
        } 
       } 
       return eachWordExpanded; 
      }).collect(Collectors.joining("|")); 

     return result; 
    } 

} 

Выход следующий:

Вход:

interoperation="{<number_type_2 digits> <number_type_1 digits> <number_type_0 words>}"; 

grammar="test is [(thirty four) {<number_type_0 words>}(3 4) {<number_type_0 digits>}] test [(three) {<number_type_1 words>}(3) {<number_type_1 digits>}] [(one) {<number_type_2 words>}(1) {<number_type_2 digits>}]"; 

тест | является | тридцать-четырь | тест | 3 | 1

Вход:

grammar="test is [(thirty four) {<number_type_0 words>}(three four) {<number_type_0 digits>}] test [(three) {<number_type_1 words>}(3) {<number_type_1 digits>}] [(one) {<number_type_2 words>}(1) {<number_type_2 digits>}]"; 

тест | является | тридцать-четырь | тест | 3 | 1

Ввод:

interoperation="{<number_type_4 digits> <number_type_3 digits> <number_type_2 words> <number_type_1 words> <number_type_0 words>}"; 
grammar="test [(thirty four) {<number_type_0 words>}(3 4) {<number_type_0 digits>}] test [(three) {<number_type_1 words>}(3) {<number_type_1 digits>}] [(one) {<number_type_2 words>}(1) {<number_type_2 digits>}]"; 

тест | тридцать-четыре | тест | три | один

Вход:

grammar = "this is my test [(three hundred forty one) {<number_type_0 words>}(3 4 1) {<number_type_0 digits>}] for [(twenty one) {<number_type_1 words>}(2 1) {<number_type_1 digits>}] issues"; 
interoperation= "{<number_type_1 digits> <number_type_0 words>}"; 

это | является | мой | тест | триста сорок один | для | 2 1 | вопросов

0

Я пишу решение, основанное на предположении, что формат вашей строки interpretation остается неизменным, т.е. {<number_type_2 digits> <number_type_1 digits> <number_type_0 words>} и он не меняется.

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

Давайте начнем ходить по коду:

Java-7 стиле

/* 
    * STEP 1: Create a method that accepts wordsExpanded and 
    * interpretation Strings 
    */ 
    public static void parseString(String wordsExpanded, String interoperation) { 
     /* 
     * STEP 2: Remove leading and tailing curly braces form 
     * interoperation String 
     */ 
     interoperation= interoperation.replaceAll("\\{", ""); 
     interoperation = interoperation.replaceAll("\\}", ""); 

     /* 
     * STEP 3: Split your interoperation String at '>' 
     * because we need individual interoperations like 
     * "<number_type_2 words" to compare. 
     */ 
     String[] allInterpretations = interoperation.split(">"); 

     /* 
     * STEP 4: Split your wordsExpanded String at '|' 
     * to get each word. 
     */ 
     String[] allWordsExpanded = wordsExpanded.split("\\|"); 

     /* 
     * STEP 5: Create a resultant StringBuilder 
     */ 
     StringBuilder resultBuilder = new StringBuilder(); 

     /* 
     * STEP 6: Iterate over each words form wordsExpanded 
     * after splitting. 
     */ 
     for(String eachWordExpanded : allWordsExpanded){ 
      /* 
      * STEP 7: Remove leading and tailing spaces 
      */ 
      eachWordExpanded = eachWordExpanded.trim(); 
      /* 
      * STEP 8: Remove leading and tailing curly braces 
      */ 
      eachWordExpanded = eachWordExpanded.replaceAll("\\{", ""); 
      eachWordExpanded = eachWordExpanded.replaceAll("\\}", ""); 

      /* 
      * STEP 9: Now, iterate over each interoperation. 
      */ 
      for(String eachInteroperation : allInterpretations){ 
       /* 
       * STEP 10: Remove the leading and tailing spaces 
       * from each interoperations. 
       */ 
       eachInteroperation = eachInteroperation.trim(); 

       /* 
       * STEP 11: Now append '>' to end of each interoperation 
       * because we'd split each of them at '>' previously. 
       */ 
       eachInteroperation = eachInteroperation + ">"; 

       /* 
       * STEP 12: Check if each eordExpanded contains any of the 
       * interoperation. 
       */ 
       if(eachWordExpanded.contains(eachInteroperation)){ 

        /* 
        * STEP 13: If each interoperation contains 
        * 'word', goto STEP 14. 
        * ELSE goto STEP 18. 
        */ 
        if(eachInteroperation.contains("words")){ 
         /* 
         * STEP 14: Remove that interoperation from the 
         * each wordExpanded String. 
         * 
         * Ex: if the interoperation is <number_type_2 words> 
         * and it is found in the wordExpanded, remove it. 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll(eachInteroperation, ""); 
         /* 
         * STEP 15: Now change the interoperation to digits. 
         * Ex: IF the interoperation is <number_type_2 words>, 
         * change that to <number_type_2 digits> and also remove them. 
         */ 
         eachInteroperation = eachInteroperation.replaceAll("words", "digits"); 
         eachWordExpanded = eachWordExpanded.replaceAll(eachInteroperation, ""); 

         /* 
         * STEP 16: Remove leading and tailing square braces 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll("\\[", ""); 
         eachWordExpanded = eachWordExpanded.replaceAll("\\]", ""); 

         /* 
         * STEP 17: Remove any numbers in the form (3), 
         * since we are dealing with words. 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll("[(0-9)+]", ""); 
         eachWordExpanded = eachWordExpanded.replaceAll("(\\s)+", " "); 
        }else{ 
         /* 
         * STEP 18: Remove the interoperation just like STEP 14. 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll(eachInteroperation, ""); 
         /* 
         * STEP 19: Now, change interoperations to words just like STEP 15, 
         * since we are dealing with digits here and then, remove it from the 
         * each wordExpanded String. 
         */ 
         eachInteroperation = eachInteroperation.replaceAll("digits", "words"); 
         eachWordExpanded = eachWordExpanded.replaceAll(eachInteroperation, ""); 

         /* 
         * STEP 20: Remove the leading and tailing square braces. 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll("\\[", ""); 
         eachWordExpanded = eachWordExpanded.replaceAll("\\]", ""); 
         /* 
         * STEP 21: Remove the words in the form '(thirty four)' 
         */ 
         eachWordExpanded = eachWordExpanded.replaceAll("[(A-Za-z)+]", ""); 
         eachWordExpanded = eachWordExpanded.replaceAll("\\s", ""); 
        } 
       }else{ 
        continue; 
       } 
      } 
      /* 
      * STEP 22: Build your result object 
      */ 
      resultBuilder.append(eachWordExpanded + "|"); 
     } 
     /* 
     * FINAL RESULT 
     */ 
     System.out.println(resultBuilder.toString()); 
} 

Эквивалент Java-8 стиль, как показано ниже:

public static void parseString(String wordsExpanded, String interoperation) { 
     interoperation= interoperation.replaceAll("\\{", ""); 
     interoperation = interoperation.replaceAll("\\}", ""); 

     String[] allInterpretations = interoperation.split(">"); 

     StringJoiner joiner = new StringJoiner(""); 
     Set<String> allInterOperations = Arrays.asList(interoperation.split(">")) 
      .stream() 
      .map(eachInterOperation -> { 
      eachInterOperation = eachInterOperation.trim(); 
      eachInterOperation = eachInterOperation + ">"; 
      return eachInterOperation; 
     }).collect(Collectors.toSet()); 

     String result = Arrays.asList(wordsExpanded.split("\\|")) 
     .stream() 
     .map(eachWordExpanded -> { 
     eachWordExpanded = eachWordExpanded.trim(); 
     eachWordExpanded = eachWordExpanded.replaceAll("\\{", ""); 
     eachWordExpanded = eachWordExpanded.replaceAll("\\}", ""); 

     for(String eachInterOperation : allInterOperations){ 
      if(eachWordExpanded.contains(eachInterOperation)){ 
       if(eachInterOperation.contains("words")){ 
        eachWordExpanded = eachWordExpanded.replaceAll(eachInterOperation, ""); 
        eachInterOperation = eachInterOperation.replaceAll("words", "digits"); 
        eachWordExpanded = eachWordExpanded.replaceAll(eachInterOperation, ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("\\[", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("\\]", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("[(0-9)+]", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("(\\s)+", " "); 
       }else{ 
        eachWordExpanded = eachWordExpanded.replaceAll(eachInterOperation, ""); 
        eachInterOperation = eachInterOperation.replaceAll("digits", "words"); 
        eachWordExpanded = eachWordExpanded.replaceAll(eachInterOperation, ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("\\[", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("\\]", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("[(A-Za-z)+]", ""); 
        eachWordExpanded = eachWordExpanded.replaceAll("\\s", ""); 
       } 
      }else{ 
       continue; 
      } 
     } 
     return eachWordExpanded; 
    }).collect(Collectors.joining("|")); 

    System.out.println(result); 
} 

на управлении следующие тесты по вышеуказанному методу с разными взаимодействиями. Строки типа:

{<number_type_2 words> <number_type_1 words> <number_type_0 words>} 
{<number_type_2 digits> <number_type_1 words> <number_type_0 words>} 
{<number_type_2 digits> <number_type_1 digits> <number_type_0 digits>} 
{<number_type_2 words> <number_type_1 digits> <number_type_0 digits>} 

будет производить результат, как (Java-7 результат):

test|is|thirty four |test|three |one | 
test|is|thirty four |test|three |1| 
test|is|34|test|3|1| 
test|is|34|test|3|one | 

(Java-8 Результат)

test|is|thirty four|test|three|one 
test|is|thirty four|test|three|1 
test|is|34|test|3|1 
test|is|34|test|3|one 

Я надеюсь, что это то, что вы были пытаясь добиться.

+0

Это здорово! Спасибо, что сказал, что некоторые строки грамматики могут иметь «один» «два» «три» ... как цифры, а не «1» «2» «3».Строка будет выглядеть так: «[тридцать четыре]] {<число_type_0 слов>} (три четыре) {<число_type_0 цифр>}]" –

+0

Ну, в этом случае, в вашей цифре loop.ie в 'else' part, удалите эту строку 'eachWordExpanded = eachWordExpanded.replaceAll (" [(A-Za-z) +] "," ");' и передайте 'eachWordExpanded' в ** конвертер/парсер ** в цифру **, который преобразует ваши слова в цифрах. Более подробную информацию о создании парсера слова-цифры можно найти здесь: http://stackoverflow.com/questions/4062022/how-to-convert-words-to-a-number –

 Смежные вопросы

  • Нет связанных вопросов^_^