2010-08-06 6 views
0

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

В моей первой версии не было никаких строк, поэтому (abc|def|[a-z]+)([0-9]*) отлично работает. Но теперь я хочу разрешить строки. (abc|def|[a-z]+)([0-9]*|[a-z]*) не работает.

Строка 1: abc20def20ghi20
Строки 2: abcdddef20ghi20
Строка 3: abcdddef2d0ghi20abcdd

Строка 1:
Пример с регулярными выражениями 1: abc20 *** def20 *** ghi20
примером с регулярным выражением 2: abc20 *** def20 *** ghi20

Строка 2:
Пример с REGE х 1: а *** dddef20 *** ghi20
Пример с регулярным выражением 2: аЬса *** dddef20 *** ghi20

Я хочу, чтобы получить следующий результат: abc20 *** def20 * ** ghi20 и abcdd *** def20 *** ghi20

Благодарим за помощь.

+1

Что означает курсив и жирный текст? – Gumbo

+0

Это невозможно. Поскольку «команды» и «параметры» состоят из букв и нет разделителя, невозможно узнать, когда закончится команда и начинается параметр. Или есть ли какие-либо другие требования к командам и параметрам? Кажется, что команды всегда имеют длину 3 символа и параметры 2. – RoToRa

+0

Жирный и курсивный текст означает распознанные группы. Возможно, я написал облачно и должен упомянуть, что я использую RegexBuddy. Параметр и команды не указали длину. В строке 2 у меня есть команда abc и параметр dd. Только когда я знаю команду, параметр важен. ghi не известен как команда, поэтому не требуется получать параметр. – CSchulz

ответ

1

Основываясь на своем последнем комментарии, возможно, это будет делать трюк для вас:

(abc|def)(\d+|(?:(?!(?1))[a-z])+)?|((?:(?!(?1))[a-z])+)((?2))? 

EDIT. К сожалению, для редактирования моего предыдущего ответа вместо публикации нового.

TEST СЛУЧАЙ:

<?php 

$r = '#(abc|def)(\d+|(?:(?!(?1))[a-z])+)?|((?:(?!(?1))[a-z])+)((?2))?#'; 
$s1 = 'abc20def20ghi20'; 
$s2 = 'abcdddef20ghi20'; 
$s3 = 'abcdddef2d0ghi20abcdd'; 

preg_match_all($r, $s1, $m1); 
preg_match_all($r, $s2, $m2); 
preg_match_all($r, $s3, $m3); 
var_dump($m1[0], $m2[0], $m3[0]); 

Выход:

array(3) { 
    [0]=> 
    string(5) "abc20" 
    [1]=> 
    string(5) "def20" 
    [2]=> 
    string(5) "ghi20" 
} 
array(3) { 
    [0]=> 
    string(5) "abcdd" 
    [1]=> 
    string(5) "def20" 
    [2]=> 
    string(5) "ghi20" 
} 
array(5) { 
    [0]=> 
    string(5) "abcdd" 
    [1]=> 
    string(4) "def2" 
    [2]=> 
    string(2) "d0" 
    [3]=> 
    string(5) "ghi20" 
    [4]=> 
    string(5) "abcdd" 
} 

Как вы можете видеть, он улавливает все детали с обеих строк корректно.

+0

Почти. :) Я думал о взгляде, но я этого не понимаю. Единственное, что он не работает полностью с String 1, dd после abc будет проигнорирован, а ghi игнорируется в обеих строках. – CSchulz

+0

Хорошо, обновил регулярное выражение, чтобы учитывать эти случаи, теперь должен работать. Я также изменил внешний вид использования '(? 1)', поэтому вам нужно только отредактировать первый список команд, если вы хотите добавить новые команды. –

+0

Очень хорошая работа, но мой RegexBuddy говорит, что есть некоторые ошибки, и я не знаю, как это исправить. Одновременно я разработал ваше регулярное выражение в очень простой версии '(abc | def | [a-z] *). +? (?! (Abc | def))'. : D – CSchulz

0

Вы всегда хотите захватить строки длиной 5? Если да, то вы можете сделать это:

([a-z]{3})([0-9a-z]{2}) 

Если нет, может быть, вы можете уточнить, что именно является критерием для «вырезать» строку между «abcdd» и «def20»?

+0

Нет, извините, но команды и параметры не имеют заданной длины. – CSchulz

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