【问题标题】:Find position of part of a INSERT statement in a string在字符串中查找部分 INSERT 语句的位置
【发布时间】:2013-01-31 04:50:21
【问题描述】:

我试图在 INSERT 语句中查找单词“VALUES”之后的字符串位置,这将是实际行数据之前的位置。

我知道我需要使用正则表达式来获取 INSERT 语句的模式,而不是使用 strpos 来查找单词“VALUES”,但是当涉及到正则表达式函数时,我有点新手。

更新

我想找到 ") VALUES (" 的位置,并在括号之间允许空格、\n、\r、\t 等,因为有时 VALUES 在新行上。

谢谢

SQL 文件:

# ------------------------------

# --
# -- Dumping data for table `table_a`
# --

INSERT INTO `table_a` (`a`, `b`, `c`, `d`) 
VALUES -- get position 
(1, 'b', 'c', 'd'),
(2, 'b', 'c', 'd'),
(3, 'b', 'c', 'd');

# ------------------------------

# --
# -- Dumping data for table `table_b`
# --

INSERT INTO `table_b` (`a`, `b`, `c`, `d`) VALUES -- get position 
(1, 'b', 'c', 'd'),
(2, 'b', 'c', 'd'),
(3, 'b', 'c', 'd');

【问题讨论】:

  • 你希望结果是什么?
  • 我真的希望你不要试图用正则表达式解析 SQL。
  • 只使用strpos() 来查找VALUES 会有什么问题?我认为VALUES 会出现的唯一其他情况是插入中的ON DUPLICATE KEY UPDATE 子句。如果你没有这些,我想不出你为什么会在表转储中,应该没有问题。
  • @arbme 然后搜索) VALUES
  • @arbme 不要误会我的意思,通常这样的事情是个坏主意,(尝试对不一定按顺序排列的数据使用正则表达式或 strpos)但如果您的用例有限在您了解数据将是什么的情况下,这可能是获得所需内容的快速而肮脏的方式。

标签: php mysql preg-match-all


【解决方案1】:

这应该可以解决问题:

$content = file_get_contents('/path/to/dump.sql');
$pattern = '/\)\s+VALUES\s+\(/U';
$matches = array();
$match_count = preg_match_all($pattern, $content, $matches, PREG_OFFSET_CAPTURE);

// trim off the parenthesis and whitespace from each match and add length of remaining portion of match string to the match offset to get offset at end of 'VALUES'
$offsets = array();
foreach($matches[0] as $match) {
    $offsets[] = $match[1] + strlen(rtrim(substr($match[0], 0, -1)));
}

【讨论】:

  • 非常感谢,需要在 foreach() 中将 $matches 编辑为 $matches[0] 以使其正常工作。谢谢
  • “/U”在正则表达式中究竟做了什么?
  • @arbme U 是一个模式修饰符,它使匹配变得不贪婪,从而匹配尽可能小的字符串。在这种情况下可能实际上不需要它,因为您匹配的唯一类是空格。但是,如果模式是/\).*VALUES.*\(/,如果模式使用其默认的贪婪行为,您可能会匹配第一个VALUES 和最后一个( 之间的几乎整个文件。您可以在有或没有U 的情况下使用该模式来自己查看差异。链接更多关于模式修饰符的信息:php.net/manual/en/reference.pcre.pattern.modifiers.php
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
  • 2012-12-24
  • 2011-04-14
  • 1970-01-01
相关资源
最近更新 更多