2013-04-26 2 views
4

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

Я пытаюсь использовать регулярное выражение ".*&([^&])*&.*", но оно не работает, я не знаю, что в этом плохого.

Любая помощь?

Благодаря

+0

Так что все по обе стороны от '&&'? – Makoto

+2

Вам нужно делать это с помощью регулярных выражений? – CodeBlue

+0

@CodeBlue: Я думаю, что regex является инструментом выбора для такого рода работы. Что вы имели в виду вместо этого? –

ответ

0

две проблемы:

  1. Вы повторив группу захвата. Это означает, что вы поймаете только последнюю букву между & s в группе.

  2. Вы будете соответствовать только последнему слову, потому что .* s сожжет остальную часть строки.

Использование lookarounds вместо:

(?<=&)[^&]+(?=&) 

Теперь весь матч будет hellobye при применении регулярных выражений во второй раз), потому что окружающие & s не будет частью матч больше:

List<String> matchList = new ArrayList<String>(); 
Pattern regex = Pattern.compile("(?<=&)[^&]+(?=&)"); 
Matcher regexMatcher = regex.matcher(subjectString); 
while (regexMatcher.find()) { 
    matchList.add(regexMatcher.group()); 
} 
6

Попробуйте этот путь

String data = "&hello&&bye&"; 
Matcher m = Pattern.compile("&([^&]*)&").matcher(data); 
while (m.find()) 
    System.out.println(m.group(1)); 

выход:

hello 
bye 
+0

он работает! спасибо: D – jackyokboy

+0

@jackyokboy Рад, что вам понравилось, но меня также интересует комментарий CorrugatedAirs о '' & hello & bye & "'. Не могли бы вы ответить и сообщить, какие результаты должны быть? – Pshemo

+0

@jackyokboy: Я надеюсь, что вы не просто слепо скопируете и вставьте это туда, где вам это нужно. Вы должны попытаться переварить, что он делает. – Makoto

0

Окружающий .* не имеют смысла и непродуктивно. Достаточно &([^&])*&.

+3

Нет, это не так. Захват группы 1 будет содержать 'o' (для первого матча) вместо' hello' и 'e' (для второго совпадения) вместо' bye'. –

+0

@TimPietzcker yes, который должен быть '([^ &] *)' вместо этого, но я просто думал об использовании всей группы (что также устранило бы необходимость захвата для начала) –

2

Нет необходимости в регулярном выражении. Просто повторяй!

boolean started = false; 
List<String> list; 
int startIndex; 
for(int i = 0; i < string.length(); ++i){ 
    if(string.charAt(i) != '&') 
     continue; 
    if(!started) { 
     started = true; 
     startIndex = i + 1; 
    } 
    else { 
     list.add(string.substring(startIndex, i)); // maybe some +-1 here in indices 
    } 
    started = !started; 
} 

или использовать сплит!

String[] parts = string.split("&"); 
for(int i = 1; i < parts.length; i += 2) { // every second 
    list.add(parts[i]); 
} 
+0

+1 для разделенной версии. Была такая же идея, но несколько минут спустя :) – Pshemo

2

Если вы не хотите использовать регулярные выражения, вот простой способ.

String string = "xyz...." // the string containing "hello", "bye" etc. 


String[] tokens = string.split("&"); // this will split the string into an array 
            // containing tokens separated by "&" 

for(int i=0; i<tokens.length; i++) 
{ 
    String token = tokens[i]; 


    if(token.length() > 0) 
     { 
      // handle edge case 
      if(i==tokens.length-1) 
      { 
        if(string.charAt(string.length()-1) == '&') 
        System.out.println(token); 
      } 
      else 
       { 
       System.out.println(token); 
       } 
     } 
} 
+0

Кажется, вы никогда не будете печатать в «краевых случаях», потому что если условия истинны, то эти токены имеют длину = 0 – RiaD

+0

@RiaD, о, это потому, что split поместит пустую строку как первый токен, когда «$» является первым символом? – CodeBlue

+0

Я исследовал его. Пустая строка будет проигнорирована, в то время как пустой пустой не будет. Java - это Java. Итак, первая проверка не нужна, а вторая - хорошая. Или вы можете использовать отрицательный предел, чтобы не игнорировать его. http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String) http://ideone.com/ZuvUfB – RiaD

0

Я бы упростил его еще дальше.

  1. Убедитесь, что первый символ &
  2. Убедитесь, что последний символ является &
  3. String.split("&&") на подстроки между ними

В коде:

if (string.length < 2) 
    throw new IllegalArgumentException(string); // or return[], whatever 
if ((string.charAt(0) != '&') || (string.charAt(string.length()-1) != '&') 
    // handle this, too 
String inner = string.substring(1, string.length()-1); 
return inner.split("&&"); 
Смежные вопросы