Php Regex:在Regex中进一步使用捕获数据

Php Regex:在Regex中进一步使用捕获数据,php,regex,Php,Regex,我想分析一些以“”开头的文本:“”,可以用括号括起来以停止匹配,因此: “abcd:(someText)efgh”和 "abcd:someText" 将返回someText 但我有一个问题,设置括号的选择 我做了这个,但它不起作用: $reg = '#:([\\(]){0,1}([a-z]+)$1#i'; $v = 'abc:(someText)def'; var_dump(preg_match($reg,$v,$matches)); var_dump($matches); $1使其失

我想分析一些以“
”开头的文本:“
”,可以用括号括起来以停止匹配,因此:

“abcd:(someText)efgh”

"abcd:someText"
将返回
someText

但我有一个问题,设置括号的选择

我做了这个,但它不起作用:

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

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

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

var_dump($matches);
$1
使其失败

我不知道如何告诉他:

如果结尾有“(“开头一定有”)”


无法测试某个计数是否等于另一个计数。这是一个正则表达式问题,只能与常规语言一起使用(http://en.wikipedia.org/wiki/Regular_language). 要实现您的目标,正如您所要求的——也就是说,如果有一个“(‘应该是’)”——您将需要一种上下文无关的语言(http://en.wikipedia.org/wiki/Context-free_language)

无论如何,您可以使用以下正则表达式:

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

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

如果$1为空,则没有括号,并且$2包含您的文本。

此正则表达式将匹配:word或:(word)组1和组2保存各自的结果

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

要将正则表达式中不同子模式的匹配返回到
$matches
数组的同一元素,可以使用以允许重复名称。
$matches
中的返回元素与模式的名称相同:

$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>';
}

正则表达式:向后看

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

”(?abcd:someOtherText“| grep-Po”)(?我不是在“计算”(“。如果设置了第一个”()则$1包含它,如果未设置第一个”()则$1将不包含任何内容。我就是这么看的。@AurelioDeRosa:regex的结果:abcd:(someText)efgh abcd someTextPCRE不再是规则的了。@AurelioDeRosa我不认为使用管道(|),听起来不错,但你为什么使用。*?正如你所看到的,另一个答案也有管道。使用管道使用正则表达式更清楚。可能:$result=($regs[1])?$regs[1]:$regs[2];@Leto我不知道php:)因此,您必须自己计算该部分:)现在编辑。@FailedDev:您可能会感兴趣;)一些文本是否包含数字?如
0
?@FailedDev:我已将指向PHP手册的链接放在那里,两个页面都包含该信息,您需要在每个页面上向下滚动一点。
"(?<=:\(|:)[^()]+"
kent$  echo "abcd:(someText)efgh
dquote> abcd:someOtherText"|grep -Po "(?<=:\(|:)[^()]+"

someText
someOtherText