SQL中的正则表达式提取函数实现?

Posted

技术标签:

【中文标题】SQL中的正则表达式提取函数实现?【英文标题】:Regex in SQL to extract the function implementation? 【发布时间】:2019-03-20 23:32:54 【问题描述】:

我必须查询 github 内容才能找到特定函数 add 的实现。我使用以下 SQL 查询提取的内容:

(function(f)if(typeof exports==="object"&&typeof module!=="undefined")

module.exports=f()else if(typeof define==="function"&&define.amd)define([],f)elsevar g;if(typeof window!=="undefined")g=windowelse if(typeof global!=="undefined")g=globalelse if(typeof self!=="undefined")g=selfelseg=thisg.ngContextmenu = f())(function()var define,module,exports;return (function e(t,n,r)function s(o,u)if(!n[o])if(!t[o])var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",fvar l=n[o]=exports:;t[o][0].call(l.exports,function(e)var n=t[o][1][e];return s(n?n:e),l,l.exports,e,t,n,r)return n[o].exportsvar i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s)(1:[function(_dereq_,module,exports)
    'use strict';

    angular.module('io.dennis.contextmenu')
    .directive('contextmenuContainer', Container);

    function Container() 
      return 
        scope: 
          contextmenu: '=contextmenuContainer'
        ,
        restrict: 'A',
        controller: ['$scope', ContainerCtrl]
      ;
    .
    .
    .
    .
      function add(entry) 
        if (!isSelected(entry)) 
          selected.unshift(entry);
          toggleSelected(entry.element, true);
        
        pub.item = selected[0].item;
      

      function remove(entry) 
        var index = selected.indexOf(entry);
        if (index > -1) 
          selected.splice(index, 1);
        
        toggleSelected(entry.element, false);
      

     .
    .
    .
      function toggle(entry, multi) 
        multi = multi || false;
        var isEntrySelected = isSelected(entry);

        if (isEntrySelected) 
          remove(entry);

         else 

          if (!multi)  clear(); 
          add(entry);
        
      

      function clear() 
        angular.forEach(selected, function(entry) 
          toggleSelected(entry.element, false);
        );
        selected = [];
      

      function getListOfIds(limit, path) 
        path = path || 'item.id';
        limit = Math.min(limit || selected.length, selected.length);
        var list = selected.slice(0, limit).map(function(entry) 
          return safeGet(entry, path, '');
        );
        var asString = list.join(', ');
        return (limit < selected.length) ? asString + '..' : asString;
      

      function toggleSelected(element, forceState) 
        element.toggleClass('selected', forceState);
      

      function safeGet(obj, path, _default) 

        if (!obj) 
          return _default;
        

        if (!path || !String(path).length) 
          return obj;
        

        var keys = (angular.isArray(path)) ? path : path.split('.');
        var next = keys.shift();
        return get(obj[next], keys, _default);
      
    

    ,],,[4])(4)
    );

还有更多这样的行。我正在使用的查询是:

SELECT
  content,
  id
FROM
  [bigquery-public-data:github_repos.sample_contents]
  WHERE
  content CONTAINS 'function add('
  AND sample_path LIKE '%.js'
  LIMIT  40;

如何修改上述查询,以便我只能提取具有输出的内容以实现函数“add”,即

function add(entry) 
    if (!isSelected(entry)) 
      selected.unshift(entry);
      toggleSelected(entry.element, true);
    
    pub.item = selected[0].item;
  

提前致谢!

【问题讨论】:

我认为仅使用正则表达式会很困难。也许如果你写了一个javascript UDF 你可以解析内容。请注意,BigQuery 支持两种 SQL 方言,并且您在示例中使用的是旧版 SQL,而上面的链接适用于标准 SQL。 我已将查询修改为 SELECT REGEXP_EXTRACT(content,r'add(.*(.|\n)*\n2,'), id FROM ( SELECT content, id FROM [bigquery-public-data:github_repos.sample_contents] WHERE content CONTAINS 'function add(' AND sample_path LIKE '%.js' LIMIT 40 ) 但也许我错过了什么。有人可以帮忙吗? @ElliottBrossard,你能给 JS udf 吗? 您能否在输出中提供与您的需求不符并且您想过滤掉的数据,您的问题不是很清楚到底是什么问题 【参考方案1】:

这是一个过度简化的 JavaScript UDF 版本,它甚至没有尝试匹配大括号,但我相信你明白了。我在 JavaScript 代码中留下了 cmets,供您完成非平凡的查找函数末尾的工作。尽情享受吧!

#standardSQL
CREATE TEMP FUNCTION
  filter_add(code STRING)
  RETURNS STRING
  LANGUAGE js AS """
  // find start, TODO: there may be multiple function add() in single file, handle in a loop
  var start = code.indexOf('function add(');
  // TODO: count open braces and close braces to decide where function definition ends.
  // Note that braces may be in 1) single-line comment; 2) multi-line comments; 3) part of string or char literal
  var end = code.indexOf('', start);
  return code.substr(start, end-start+1);
  """ ;
SELECT
  filter_add(content), id
FROM
  `bigquery-public-data`.github_repos.sample_contents
WHERE
  STRPOS(content, 'function add(') != 0
  AND sample_path LIKE '%.js'
LIMIT 10;

【讨论】:

以上是关于SQL中的正则表达式提取函数实现?的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql语句中使用正则表达式

sql server中对字段使用正则表达式替换???

Oracle正则表达式

了解熊猫系列提取函数中的正则表达式

PHP正则表达式提取html超链接中的href地址

自动化办公:手机号码提取器,使用正则表达式轻松提取文本文件中的手机号码