Как разбить строку, но также сохранить разделители? - PullRequest
209 голосов
/ 05 февраля 2010

У меня есть многострочная строка, которая разделена набором различных разделителей:

(Text1)(DelimiterA)(Text2)(DelimiterC)(Text3)(DelimiterB)(Text4)

Я могу разбить эту строку на части, используя String.split, но кажется, что я не могу получить фактическую строку, которая соответствует регулярному выражению разделителя.

Другими словами, вот что я получаю:

  • Text1
  • Text2
  • Text3
  • Text4

Это то, что я хочу

  • Text1
  • DelimiterA
  • Text2
  • DelimiterC
  • Text3
  • DelimiterB
  • Text4

Есть ли какой-нибудь способ JDK разбить строку с помощью регулярного выражения-разделителя, но также оставить разделители?

Ответы [ 23 ]

0 голосов
/ 09 ноября 2008

Быстрый ответ: используйте нефизические границы, такие как \ b, для разделения. Я попытаюсь поэкспериментировать, чтобы увидеть, работает ли он (использовал это в PHP и JS).

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

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

Мой быстрый тест:

String str = "'ab','cd','eg'";
String[] stra = str.split("\\b");
for (String s : stra) System.out.print(s + "|");
System.out.println();

Результат:

'|ab|','|cd|','|eg|'|

Слишком много ...: -)

0 голосов
/ 02 июня 2019

Одна из тонкостей в этом вопросе связана с вопросом «ведущего разделителя»: если у вас будет комбинированный массив токенов и разделителей, вы должны знать, начинается ли он с токена или разделителя. Конечно, вы можете просто предположить, что ведущий разделитель должен быть отброшен, но это кажется неоправданным предположением. Вы также можете узнать, есть ли у вас конечный разделитель или нет. Это устанавливает два логических флага соответственно.

Написано на Groovy, но версия Java должна быть довольно очевидной:

            String tokenRegex = /[\p{L}\p{N}]+/ // a String in Groovy, Unicode alphanumeric
            def finder = phraseForTokenising =~ tokenRegex
            // NB in Groovy the variable 'finder' is then of class java.util.regex.Matcher
            def finderIt = finder.iterator() // extra method added to Matcher by Groovy magic
            int start = 0
            boolean leadingDelim, trailingDelim
            def combinedTokensAndDelims = [] // create an array in Groovy

            while( finderIt.hasNext() )
            {
                def token = finderIt.next()
                int finderStart = finder.start()
                String delim = phraseForTokenising[ start  .. finderStart - 1 ]
                // Groovy: above gets slice of String/array
                if( start == 0 ) leadingDelim = finderStart != 0
                if( start > 0 || leadingDelim ) combinedTokensAndDelims << delim
                combinedTokensAndDelims << token // add element to end of array
                start = finder.end()
            }
            // start == 0 indicates no tokens found
            if( start > 0 ) {
                // finish by seeing whether there is a trailing delim
                trailingDelim = start < phraseForTokenising.length()
                if( trailingDelim ) combinedTokensAndDelims << phraseForTokenising[ start .. -1 ]

                println( "leading delim? $leadingDelim, trailing delim? $trailingDelim, combined array:\n $combinedTokensAndDelims" )

            }
0 голосов
/ 09 ноября 2008

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

string[] mySplit(string s,string delimiter)
{
    string[] result = s.Split(delimiter);
    for(int i=0;i<result.Length-1;i++)
    {
        result[i] += delimiter; //this one would add the delimiter to each items end except the last item, 
                    //you can modify it however you want
    }
}
string[] res = mySplit(myString,myDelimiter);

Это не слишком элегантно, но подойдет.

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