2010-12-08 9 views
2

Моя группа может иметь форму x/y, x.y или x_y.z. Каждая группа разделяется символом подчеркивания. Группы неупорядочены.Regex для захвата групп

Пример:

ABC/DEF_abc.def_PQR/STU_ghi_jkl.mno 

Я хотел бы, чтобы захватить следующее:

ABC/DEF 
abc.def 
PQR/STU 
ghi_jkl.mno 

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

private static ArrayList<String> go(String s){ 
    ArrayList<String> list = new ArrayList<String>(); 
    boolean inSlash = false; 
    int pos = 0 ; 
    boolean inDot = false; 
    for(int i = 0 ; i < s.length(); i++){ 
     char c = s.charAt(i); 
     switch (c) { 
     case '/': 
      inSlash = true; 
      break; 
     case '_': 
      if(inSlash){ 
       list.add(s.substring(pos,i)); 
       inSlash = false; 
       pos = i+1 ; 
      } 
      else if (inDot){ 
       list.add(s.substring(pos,i)); 
       inDot = false; 
       pos = i+1; 
      } 
      break; 
     case '.': 
      inDot = true; 
      break; 
     default: 
      break; 
     } 

    } 
    list.add(s.substring(pos)); 
    System.out.println(list); 
    return list; 
} 
+0

Подчеркивание может быть строка-разделитель а как часть группы? – 2010-12-08 12:49:42

+0

Трудность, кажется, в последнем типе группы (с подчеркиванием в ней). Не могли бы вы немного рассказать о правилах, когда подчеркивание должно быть частью группы, и когда это должен быть символ разделителя? Возможно, вы можете опубликовать свой текущий код. – Jordi 2010-12-08 12:50:17

+0

да, это забавная часть :) Может быть, какой-то способ взглянуть на точку, а затем определить, является ли она делимкой или группой? – dogbane 2010-12-08 12:51:04

ответ

2

У попробовать с:

((?:[^_./]+/[^_./]+)|(?:[^_./]+\.[^_./]+)|(?:[^_./]+(?:_[^_./]+)+\.[^_./]+)) 

Я не знаю синтаксис Java, но в Perl:

#!/usr/bin/perl 
use 5.10.1; 
use strict; 
use warnings; 

my $str = q!ABC/DEF_abc.def_PQR/STU_ghi_jkl.mno_a_b_c.z_a_b_c_d.z_a_b_c_d_e.z!; 
my $re = qr!((?:[^_./]+/[^_./]+)|(?:[^_./]+\.[^_./]+)|(?:[^_./]+(?:_[^_./]+)+\.[^_./]+))!; 
while($str=~/$re/g) { 
    say $1; 
} 

будет производить:

ABC/DEF 
abc.def 
PQR/STU 
ghi_jkl.mno 
a_b_c.z 
a_b_c_d.z 
a_b_c_d_e.z 
0

Возможно, проблема с подчеркиванием, поскольку это не всегда разделитель.

Может быть: ((?<=_)\w+_)?\w+[./]\.w+

+0

Пожалуйста, будьте предельно осторожны с помощью `\ w` в регулярных выражениях Java: это почти всегда неправильно (http://stackoverflow.com/questions/4304928/unicode-equivalents-for-w-and- б-в-ява-регулярных выражений/4307261 # 4307261). ☹ – tchrist 2010-12-08 15:07:04

0

Это регулярное выражение будет, вероятно, (проверено с .Net регулярными выражениями):

[a-zA-Z]+[./][a-zA-Z]+|[a-zA-Z]+_[a-zA-Z]+\.[a-zA-Z]+ 

(Если вы знаете, что ваш вход хорошо сформировавшимися нет необходимости явно соответствовать отделитель)

0

Это один идет с положительным опережающего просмотра вместо чередований

[A-Za-z]+(_(?=[A-Za-z]+\.[A-Za-z]+))?[A-Za-z]+[/.][A-Za-z]+ 
Смежные вопросы