2014-12-15 4 views
0

У меня есть строка SQL, и мне нужно получить имя таблицы из основного значения «FROM». Мне нужно найти последнее событие «FROM», которое может иметь или не иметь дополнительных ограничений после него. Вот несколько способов, строка может выглядеть:Получить после последнего вхождения в строку с использованием регулярных выражений

$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account WHERE title = 'president'"; 
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account LIMIT 1"; 
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account OFFSET 3"; 
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account ANYTHING_HERE_REALLY"; 
$input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"; 

Ожидаемый результат для всех является: счета

От соскабливать форум любой играющий вокруг, это направление я иду, но я знаю, это неправильно.

preg_match('/.*FROM\s([^]]+)\sWHERE/', $input, $output); 

ответ

0

Прежде всего, это плохая практика, чтобы использовать регулярные выражения для каскадного контента как (каскадных) запросов. Но вот мы идем ...

Просто сопоставьте последовательность без пробелов после FROM.

Примечания: из-за greedyness в Клини звезда .*, это, безусловно, искать последний матч. Вы на самом деле нацелены на недооценку проблемы, ожидая предложения WHERE.

preg_match('/.*FROM\s+(\S+)/', $input, $output); 

Пример (с приведенными примерами и интерактивные php -a):

$ php -a 
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account WHERE title = 'president'"; 
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output); 
array(2) { 
    [0]=> 
    string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account" 
    [1]=> 
    string(7) "Account" 
} 
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account LIMIT 1"; 
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output); 
array(2) { 
    [0]=> 
    string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account" 
    [1]=> 
    string(7) "Account" 
} 
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account OFFSET 3"; 
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output); 
array(2) { 
    [0]=> 
    string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account" 
    [1]=> 
    string(7) "Account" 
} 
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account ANYTHING_HERE_REALLY"; 
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output); 
array(2) { 
    [0]=> 
    string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account" 
    [1]=> 
    string(7) "Account" 
} 
php > $input = "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account"; 
php > preg_match('/.*FROM\s+(\S+)/', $input, $output);var_dump($output); 
array(2) { 
    [0]=> 
    string(80) "SELECT title, (SELECT name FROM Contact WHERE name = 'foo') as name FROM Account" 
    [1]=> 
    string(7) "Account" 
} 
+0

Замечательно. Вы не единственный, кто вызвал беспокойство по поводу использования регулярного выражения в синтаксисе запроса, но это действительно для информационных целей, поэтому я не против, если по какой-то странной причине ничего не возвращается. Я ценю вас, глядя на факт. Это был именно то, чего я пытался добиться в течение последнего часа. – nateiler

0

Это должно работать для вас:

preg_match_all('/FROM\s?(\S+)/', $input, $output); 

$ выход:

Array 
(
    [0] => Array 
     (
      [0] => FROM Contact 
      [1] => FROM Account 
     ) 

    [1] => Array 
     (
      [0] => Contact 
      [1] => Account 
     ) 

)