Есть строка:
text {msg ru key}
text text {msg key [m=1,p=1]}
text {msg ru key
[m=la la|p=1]}
text
Как видим в ней есть тег {msg}
.
Как составить регулярку так, чтобы она разбирала этот тег?
Если тег написан так: {msg ru key}
то тогда вывод нужно такой:
array(
0 => ru,
1 => key
);
Если тег написан так: {msg ru key [m=la la|p=1]}
то тогда вывод нужно такой:
array(
0 => ru,
1 => key,
2 => [m=la la|p=1]
);
Если тег написан так: {msg key [m=la la|p=1]}
то тогда вывод нужно такой:
array(
0 => key,
1 => [m=la la|p=1]
);
Предлагаю не самое простое решение, но это единственное решение, основанное на одном регулярном выражении. Чтобы найти несколько совпадений внутри какой-то определённой подстроки, нужно использовать шаблон на основе оператора \G
(=начало строки или конец предыдущего совпадения).
'~(?:(?!^)\G|{msg)\s+\K(?:\w+|\[[^][]*])(?=[^}]*})~'
См. демо регулярного выражения.
(?:(?!^)\G|{msg)
- конец предыдущего совпадения ((?!^)\G
) или (|
) подстрока {msg
\s+
- 1 и более пробельных символов\K
- оператор, очищающий буфер текущего совпадения (будто ничего не нашли до сих пор) (?:\w+|\[[^][]*])
- одно из двух:
\w+
- 1 и более букв, цифр или _
|
- или\[[^][]*]
- подстрока вида [...]
(между скобками не может быть других скобок)(?=[^}]*})
- (блок предварительного просмотра вперёд) после данного места в строке не может быть 0 и более символов, отличных от }
, а потом }
.Если просто использовать это выражение для строки, в которой есть несколько подстрок {msg...}
, найдены будут все совпадения, но они не будут группированы (см. PHP-демо). Чтобы их сгруппировать, надо использовать немного кода:
$re = '/(?:(?!^)\G|({msg))\s+\K(?:\w+|\[[^][]*])(?=[^}]*})/';
$str = 'text {msg ru key} text text {msg key [m=1,p=1]} text {msg ru key [m=la la|p=1]} text';
$results = [];
$tmp = -1;
preg_replace_callback($re, function($m) use (&$results, &$tmp) {
if (!empty($m[1])) {
array_push($results, array($m[0]));
$tmp=$tmp+1;
} else {
$results[$tmp][] = $m[0];
}
}, $str);
print_r($results);
См. PHP-демо. Результат:
Array
(
[0] => Array
(
[0] => ru
[1] => key
)
[1] => Array
(
[0] => key
[1] => [m=1,p=1]
)
[2] => Array
(
[0] => ru
[1] => key
[2] => [m=la la|p=1]
)
)
Я не уверен, но мне кажется тут придется пройтись регулярным выражением два раза, т.к. иначе у все Ваши "элементы тегов" (или что это? как Вы это называете-то?) будут в одной единой куче и их неприятно будет разбирать.
Первый раз делаете:
preg_match_all('/{msg (.*?)}/', $a, $matches);
Затем делаете:
foreach($matches[1] as $match) {
preg_match_all('/\[.*?\]|\b[^\s]+\b/', $match, $sub_matches);
// делаете что хотели с $sub_matches[0];
}
В одну регулярку такой результат не выйдет получить. Почему ответ здесь PHP has no support for captures of the same group
$string = 'text {msg ru key} text text {msg key [m=1,p=1]} text {msg ru key [m=la la|p=1]} text';
preg_match_all('#(?<={)[^}]+(?=})#', $string, $matches);
$result = [];
foreach($matches[0] as $item_match){
preg_match_all('#(\w+)|(\[[^]]+\])#', $item_match, $sub_matches);
$result[] = $sub_matches[0];
}
print_r($result);
Вывод
Array
(
[0] => Array
(
[0] => msg
[1] => ru
[2] => key
)
[1] => Array
(
[0] => msg
[1] => key
[2] => [m=1,p=1]
)
[2] => Array
(
[0] => msg
[1] => ru
[2] => key
[3] => [m=la la|p=1]
)
)
Как я понял, встроенная функция в С++ это аналог макроса СиНо в книге прочел, что встраиванием кода встроенной функции занимается компилятор,...
Когда делаю отладку консоль включается, но в нее ничего не записываетсяЯ перекачивал Visual Studio 4 раза и все равно не работает
Как сделать так чтобы программа работала, скажем циклом, но ждала ввода информации? Допустим у нас есть бесконечный цикл, который перечисляет...