如何在此模式的主题中找到字符串匹配 {{ @sql( query ) }}
How to find a string match within a subject for this pattern {{ @sql( query ) }}
我正在尝试使用 php 查找模式匹配。
我的字符串包含这样的内容
{{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}
我需要return以下数据
- 字符串匹配的部分
- 介于
{{@sql(
和)}
之间的字符串
- 任何以冒号开头的关键字
:
例如,如果我有以下字符串
$subject = 'Hello This is a test. The value found is "{{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}".';
那么对于第一颗子弹,我需要 return {{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}
对于第二个项目符号,我需要 return select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id
对于最后一个项目符号,我会 return 一个包含 :alt_id_1
和 :id
的数组
这是我试过的
$pattern = '/\{\{\s*+@sql(*)+\s*+\}\}/i';
$matches = [];
preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
echo '<pre>';
print_r($matches );
echo '</pre>';
但它给了我一个例外
preg_match_all(): Compilation failed: nothing to repeat at offset 13
括号是特殊字符。所以如果你想要文字括号,你应该转义它们
$pattern = '/\{\{\s*+@sql\([^\)]*\)\s*+\}\}/i';
已将 (*)+
更改为 \([^\)]*\)
编译错误来自 )+
,因为它无法将 )
识别为中继器 (+
) 的有效字符。
您无法使用 PREG 和大多数其他正则表达式语法捕获重复的子模式。
所以,你可以试试这个:
$pattern = '/\{\{\s*+@sql\((.+(\:[^ ]+))+.*\)+\s*+\}\}/i';
但 preg_match_all
将捕获 仅最后一个子模式 。
如果你事先知道所有主题将具有完全相同数量的 :xxx
个子字符串,你可以这样设置模式:
$pattern = '/\{\{\s*+@sql\((.+(\:[^ ]+).+(\:[^ ]+).*)\)+\s*+\}\}/i';
否则你得运行两个不同的preg_match
:
$pattern1 = '/\{\{\s*+@sql\((.+)\)+\s*+\}\}/i';
$pattern2 = '/:[^ ]+/i';
preg_match ( $pattern1, $subject, $matches, PREG_OFFSET_CAPTURE );
preg_match_all( $pattern2, $matches[1][0], $repeating, PREG_OFFSET_CAPTURE );
编辑:
来自官方PHP Documentation:
When a capturing subpattern is repeated, the value captured is the substring that matched the final iteration
我正在尝试使用 php 查找模式匹配。
我的字符串包含这样的内容
{{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}
我需要return以下数据
- 字符串匹配的部分
- 介于
{{@sql(
和)}
之间的字符串 - 任何以冒号开头的关键字
:
例如,如果我有以下字符串
$subject = 'Hello This is a test. The value found is "{{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}".';
那么对于第一颗子弹,我需要 return {{ @sql( select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id ) }}
对于第二个项目符号,我需要 return select [name] from [table] where [col1] = 50 AND [col2] = :alt_id_1 AND [col3] = :id
对于最后一个项目符号,我会 return 一个包含 :alt_id_1
和 :id
这是我试过的
$pattern = '/\{\{\s*+@sql(*)+\s*+\}\}/i';
$matches = [];
preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
echo '<pre>';
print_r($matches );
echo '</pre>';
但它给了我一个例外
preg_match_all(): Compilation failed: nothing to repeat at offset 13
括号是特殊字符。所以如果你想要文字括号,你应该转义它们
$pattern = '/\{\{\s*+@sql\([^\)]*\)\s*+\}\}/i';
已将 (*)+
更改为 \([^\)]*\)
编译错误来自 )+
,因为它无法将 )
识别为中继器 (+
) 的有效字符。
您无法使用 PREG 和大多数其他正则表达式语法捕获重复的子模式。
所以,你可以试试这个:
$pattern = '/\{\{\s*+@sql\((.+(\:[^ ]+))+.*\)+\s*+\}\}/i';
但 preg_match_all
将捕获 仅最后一个子模式 。
如果你事先知道所有主题将具有完全相同数量的 :xxx
个子字符串,你可以这样设置模式:
$pattern = '/\{\{\s*+@sql\((.+(\:[^ ]+).+(\:[^ ]+).*)\)+\s*+\}\}/i';
否则你得运行两个不同的preg_match
:
$pattern1 = '/\{\{\s*+@sql\((.+)\)+\s*+\}\}/i';
$pattern2 = '/:[^ ]+/i';
preg_match ( $pattern1, $subject, $matches, PREG_OFFSET_CAPTURE );
preg_match_all( $pattern2, $matches[1][0], $repeating, PREG_OFFSET_CAPTURE );
编辑:
来自官方PHP Documentation:
When a capturing subpattern is repeated, the value captured is the substring that matched the final iteration