给定一个字符串,匹配第一次出现单词后出现的所有内容。这个词不能出现在一对括号内的任何地方,但其他词可能会出现。例如:
SELECT
t1.col1,
(SELECT t2.col1 FROM table2 t2
WHERE t2.id IN(SELECT * FROM table5 WHERE id = t2.id)
) AS alias1,
t1.col2
----------
FROM
table1 t1,
(SELECT id FROM table3 t3 WHERE t3.id = t1.table3_id) t3,
table4 t4
我正在寻找虚线之后的所有内容 - 特别是在第一次出现单词FROM
之后的所有内容,它不出现在一对圆括号中
如果Regex不这样做,我将制作一个PHP语句进行解析。我也很难过,所以!我想要做到这一点,我将不得不用括号中的字和字符串来标记字符串?
答案 0 :(得分:1)
我认为正则表达式可能不是最好的解决方案,因为当涉及到嵌套的parens时,它们可能是非常困难(或不可能)。
我还认为循环遍历每个字符并不是最好的方法,因为它会导致很多不必要的循环。
我认为这是最好的方法:
查找给定字符串的每个出现并计算出现之前的parens数。如果开始数量等于结算数量,则表示您具有正确的匹配。这将导致更少的循环,你只是检查你真正要检查的内容。
我创建了一个采用这种方法的函数findWord
。它适用于您的SQL语句$in
且$search
为'FROM'
的示例。
function findWord( $in, $search ) {
if( strpos($in, $search) === 0 ) return $in;
$before = '';
while( strpos($in, $search, 1) ) {
$i = strpos($in, $search, 1);
$before .= substr($in, 0, $i);
$in = substr($in, $i);
$count = count_chars($before);
if( $count[40] == $count[41] )
return $in;
}
return false;
}
答案 1 :(得分:0)
除非有人有更好的答案,否则我会采用程序化方法。
/**
* Find the portion of the SQL statement occurring after
* the first occurrence of the word 'FROM' (which itself
* does not appear within parens)
*/
public static function sql_after_from($sql) {
$arr = str_split($sql);
$indent = 0;
$out = '';
$start = 0;
$len = count($arr);
for($x=0; $x < $len; $x++) {
$c = $arr[$x]; //current character
if($c == '(') $indent++;
if($c == ')') $indent--;
$out .= $arr[$x];
//do the last 4 letters spell FROM?
if(substr($out, $x-3, $x) == 'FROM') {
if($indent == 0) { //not anywhere within parens
$start = $x+2;
break; //go no further
}
}
}
//everything after the first occurrence of FROM
return substr($sql, $start);
}