2015-04-23 2 views
2

Я пытаюсь написать код в java, который похож на команду split() в Java, но не удаляет части, соответствующие регулярному выражению. Например:Java - Справка по использованию «split()»

String str = "ABC---DEF***GHI///JKL#@!"; 

Тогда

`str.split("[A-Za-z0-9]+")` returns `{"---", "***", "///", "#@!"}`. 

Однако, я хочу написать метод, аналогичный split(), который расщепляет строку AT матчей регулярного выражения, а не вокруг него.

`An example of an implementaion would be: 
public static String[] splitString(String input, String regex)` 

Таким образом:

`splitString("ABC---123DEF***456GHI///JKL9#@6!", "[A-Za-z0-9]+")` 

даст:

`{"ABC", "---", "123DEF", "***", "456GHI", "///", "JKL9", "#@", "6", "!"}` 
+0

Что вы написали до сих пор? –

+0

Я начинаю свежий. –

+0

Итак, вы хотите иметь как результат, так и результат сплит + сопоставленный шаблон? –

ответ

2

Как отмечали другие плакаты, один из способов сделать это - использовать свой узор, а затем инверсный. Это может быть достигнуто с помощью одного регулярного выражения, ([A-Za-z0-9]*)([^A-Za-z0-9]*)

String str = "ABC---DEF***GHI///JKL#@!"; 
Matcher m = Pattern.compile("([A-Za-z0-9]*)([^A-Za-z0-9]*)").matcher(str); 
List<String> result = new ArrayList<>(); 
while(m.find()) { 
    for(int i=1; i<=m.groupCount(); i++) { 
     if(!m.group(i).isEmpty()) { 
      result.add(m.group(i)); 
     } 
    } 
} 
System.out.println(StringUtils.join(result, ", ")); 

Выход:

ABC, ---, 123DEF, ***, 456GHI, ///, JKL9, #@, 6, ! 
+0

Вы должны изменить регулярное выражение так же, как и «+++ ABC ---...» (+1) – SubOptimal

+0

Хорошая точка. Обновлено. – beerbajay

1

Из-за регулярных выражений групп ограничены, я думаю, единственный способ разделить на your_pattern и анты-your_pattern и объединяйте результаты 1 на 1, например:

ANTY-regex is [^A-Za-z0-9]+ для вас. (^ В начале [] нивелируют межд)

public String[] splitString(String input, String regex, String antiRegex) 
{ 
    String[] letters = input.split(regex); 
    String[] symbols = input.split(antiRegex); 
    String[] result = new String[letters.length + symbols.length]; 
    for (int i = 0; i < letters.length; i++) 
    { 
     result[i] = letters[i]; 
     if (++i < symbols.length) //important: ++i, NOT i++ 
     { 
      result[i] = symbols[i]; 
     } 
    } 
    return result; 
} 

UPD: нет никакой проверки, если последовательность lettess является первым во входной строке, так что если вам нужно добавить идентификатор.

1

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

Pattern literals="(^[A-Za-z0-9]+)"; 
Pattern everythingElse="(^[^A-Za-z0-9]+)"; 
List<String> results; 

while(str is not finished){ 
Matcher literalsMatcher= literals.matcher(str); 
if(literalsMatcher.find()){ 
    results.add(literalsMatcher.group(1)); 
    str.subString(0,literalsMatcher.group(1).length(); 
} 

Matcher everythingElseMatcher = everythingElse.matcher(str); 
if(everythingElseMatcher.find()){ 
    results.add(everythingElseMatcher.group(1)); 
    str.subString(0,everythingElseMatcher.group(1).length(); 
} 

}

Что-то вроде этого. Извините за плохой код, но я думаю, вы можете получить эту идею.

2

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

Следующий метод показывает, где все матчи регулярного выражения являются:

public static void findMatches(String input, String regex) 
{ 
    Matcher matcher = Pattern.compile(regex).matcher(input); 

    while (matcher.find()) { 
     System.out.printf("%d-%d%n", matcher.start(), matcher.end()); 
    } 
} 

Теперь использовать индексы, которые вы найдете в этом случае вместе с String.substring(beginIndex, endIndex) создать массив строк с расколом результата вы хотите.

+0

Это действительно лучшее решение, чем те, которые были включены (мои включены) с использованием инвертированного регулярного выражения. – beerbajay

0

Здесь у вас есть рецидивирующий версия:

public static String[] split(String msg, String expr){ 
     if (msg.split(expr).length == 1){ 
     return msg.split(expr); 
     } 
     String[] tab = msg.split(expr, 2); 
     String exprStr = msg.substring(tab[0].length(), msg.length() - tab[1].length()); 
     int exprLength = msg.length() - tab[0].length() - tab[1].length(); 
     String[] tab1 = split(msg.substring(tab[0].length() + exprLength, msg.length()), expr); 
     String[] result = new String[1 + 1 + tab1.length]; 
     result[0] = tab[0]; 
     result[1] = exprStr; 
     for (int i = 0; i < tab1.length;++i){ 
     result[i + 2] = tab1[i]; 
     } 
     return result; 

}

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