2010-06-07 7 views
0

У меня есть строка 1/temperatoA,2/CelcieusB!23/33/44,55/66/77, и я хотел бы извлечь слова temperatoA и CelcieusB.выдержка слово с регулярным выражением

У меня есть это регулярное выражение (\d+/(\w+),?)*!, но я только получить матч 1/temperatoA,2/CelcieusB!

Почему?

+0

Какое средство регулярного выражения вы используете? – Johnsyweb

+1

Вам нужно принять ответ. – 0x499602D2

ответ

1

Вопрос здесь: почему вы используете регулярное выражение, которое явно ошибочно? Как ты получил это?

Выражение вы хотите просто следующим образом:

(\w+) 
+0

i bekomme nothing – farka

+0

Я использую регулярное выражение, я хочу только temperatoA и CelcieusB vor! – farka

+1

@farka: Покажите нам, как вы используете выражение. Это не выражение, это неправильно, так оно и используется. –

1

С Perl-совместимым регулярных выражений можно искать

(?<=\d/)\w+(?=.*!) 

(?<=\d/) утверждает, что есть цифра и слэш перед начало матча

\w+ соответствует идентификатору. Это позволяет использовать буквы, цифры и подчеркивание. Если вы хотите только разрешить письма, используйте вместо этого [A-Za-z]+.

(?=.*!) утверждает, что впереди в строке находится ! - i. е. регулярное выражение не будет выполнено, как только мы пройдем !.

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

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

myregexp = pcre_compile("(?<=\\d/)\\w+(?=.*!)", 0, &error, &erroroffset, NULL); 
+0

i use pcrl perl comapatibe регулярное выражение – farka

+0

В каком языке программирования? PCRE доступен для разных языков. Хорошей новостью является то, что регулярное выражение будет работать, потому что PCRE поддерживает lookaround. –

+0

, но не работает :-))) – farka

0
Будет ли

эту работу?

/([[:alpha:]]\w+)\b(?=.*!) 

я сделал следующие предположения ...

  1. слово начинается с буквенным символом.
  2. Слово всегда следует за косой чертой. Нет промежуточных пространств, нет слов посередине.
  3. Слова после восклицательного знака игнорируются.
  4. У вас есть какая-то петля для захвата нескольких слов. Я не достаточно знаком с библиотекой C, чтобы привести пример.

[[:alpha:]] соответствует любому алфавиту.

\b соответствует границе слова.

И (?=.*!) пришел с Tim Pietzcker's post.

7

Вашего все матча вычисляет '1/temperatoA,2/CelcieusB' потому, что соответствует следующему выражению:

qr{ (  # begin group 
     \d+ # at least one digit 
    / # followed by a slash 
    (\w+) # followed by at least one word characters 
    ,?  # maybe a comma 
    )*  # ANY number of repetitions of this pattern. 
}x; 

'1/temperatoA,' выполняет захват # 1 первыми, но так как вы просите двигатель, чтобы захватить как многие из тех, кто, как он может это возвращается и обнаруживает, что шаблон повторяется в '2/CelcieusB' (запятая не нужна). Таким образом, весь матч, что вы сказали, что это, но то, что вы, вероятно, не ожидали, что '2/CelcieusB'заменяет'1/temperatoA,', как $1, так $1 читает '2/CelcieusB'.

В любое время, когда вы хотите захватить все, что соответствует определенному шаблону в определенной строке, всегда лучше использовать флаг *** g *** lobal и назначить захваты в массив. Поскольку массив не является одним скаляром, например $1, он может содержать все значения, которые были захвачены для захвата # 1.

Когда я делаю это:

my $str = '1/temperatoA,2/CelcieusB!23/33/44,55/66/77'; 
my $regex = qr{(\d+/(\w+))}; 
if (my @matches = $str =~ /$regex/g) { 
    print Dumper(\@matches); 
} 

Я получаю это:

$VAR1 = [ 
      '1/temperatoA', 
      'temperatoA', 
      '2/CelcieusB', 
      'CelcieusB', 
      '23/33', 
      '33', 
      '55/66', 
      '66' 
     ]; 

Теперь, я полагаю, что это, вероятно, не то, что вы ожидали. Но '3' и '6' являются словами символов, и поэтому - после косой черты - они соответствуют выражению.

Так что, если это вопрос, вы можете изменить регулярное выражение в эквиваленте: qr{(\d+/(\p{Alpha}\w*))}, указав, что первый символ должен быть альфа с последующим любым количеством символов слова. Тогда свалка выглядит следующим образом:

$VAR1 = [ 
      '1/temperatoA', 
      'temperatoA', 
      '2/CelcieusB', 
      'CelcieusB' 
     ]; 

И если вы хотите только 'temperatoA' или 'CelcieusB', то вы захватывая больше, чем нужно, и вы хотите, чтобы ваше регулярное выражение будет qr{\d+/(\p{Alpha}\w*)}.

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

+0

+1 Это похоже на проклятое прекрасное объяснение мне - выше и выше вызова долга. – Mike