开发者

Regex: Using capture data further in the regex

I want to parse some text that start with ":" and could be surround with parentheses to stop the match so:

"abcd:(so开发者_StackOverflow中文版meText)efgh" and

"abcd:someText"

will return someText.

but i have a problem to set the parentheses optionnal.

I make this but it does not works:

$reg = '#:([\\(]){0,1}([a-z]+)$1#i';

$v = 'abc:(someText)def';

var_dump(preg_match($reg,$v,$matches));

var_dump($matches);

The $1 makes it failed.

i don't know how to tell him :

If there is a "(" at the beginning, there must be ")" at the end.


You can't test if the count of something is equal to another count. It's a regex problem who can only be used with regular language (http://en.wikipedia.org/wiki/Regular_language). To achieve your goal, as you asked - and that is if there's a '(' should be a ')' -, you'll need a Context-Free Language (http://en.wikipedia.org/wiki/Context-free_language).

Anyway, you can use this regex:

'/:(\([a-z]+\)|[a-z]+)/i


To return the match of different sub-patterns in the regex to the same element of the $matches array, you can use named subpattern with the internal option J to allow duplicate names. The return element in $matches is the same as the name of the pattern:

$pattern = '~(?J:.+:\((?<text>[^)]+)\).*|.+:(?<text>.+))~';

$texts = array(
    'abc:(someText)def',
    'abc:someText'
);

foreach($texts as $text) 
{
    preg_match($pattern, $text, $matches);
    echo $text, ' -> ', $matches['text'], '<br>';
}

Result:

abc:(someText)def -> someText
abc:someText -> someText

Demo


This regex will match either :word or :(word) groups 1 and 2 hold the respective results.

if (preg_match('/:([a-z]+)|\(([a-z]+)\)/i', $subject, $regs)) {
$result = ($regs[1])?$regs[1]:$regs[2];
} else {
$result = "";
}


regex: with look-behind

"(?<=:\(|:)[^()]+"

test with grep:

kent$  echo "abcd:(someText)efgh
dquote> abcd:someOtherText"|grep -Po "(?<=:\(|:)[^()]+"

someText
someOtherText


Try this

.+:\((.+)\).*|.+:(.+)

if $1 is empty there are no parentheses and $2 has your text.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜