【问题标题】:sql: regular expression for certain pattern separationsql:用于某些模式分离的正则表达式
【发布时间】:2019-01-01 14:27:37
【问题描述】:

在“示例”表中,我有一列“col1”,其中包含以下字符串

    some example text here x2.0.3-a abc
    some other example text 1.5 abc
    another example text 0.1.4 mnp
    some other example text  abc
    another example text mnp

现在我需要做一些事情

  1. .之前的部分添加到另一列“col1”
  2. . 部分添加到另一列“col2”

所以输出应该是这样的

       col1                  col2
some example text here      x2.0.3-a
some other example text     1.5 
another example text        0.1.4 
some other example text 
another example text 

col1中字符串的一些属性是

  1. col1 中的字符串始终以abcmnp 结尾
  2. x2.0.3-a0.1.4 这样的数字是属性。这些属性可能并不总是存在于 col1 字符串中。但如果它退出,那么它总是存在于结束字符串abcmnp 之前。
  3. 在属性之前和属性之后总是有一个空格,即结束字符串 abc/mnp 和属性之间的另一个空格。

所以我的问题是如何分离属性并将它们添加到 col2 中? 我脑海中浮现的一个想法是尝试用*.* abc/mnp*.*.* abc/mnp 找到任何东西.anything. 空间abc/mnp 或任何东西.anything.anything 空间abc/mnp。我不确定我是否解释得当。

【问题讨论】:

  • 您使用的是什么关系型数据库?数据库在正则表达式的作用上有所不同。
  • 我正在使用 Oracle
  • 能否详细说明col2的数据信息?除了您提供的模式之外,是否还有其他模式,例如 x3.1-aversion4.5

标签: sql regex oracle


【解决方案1】:

据我了解,您希望将列拆分为 3 列。你应该更好地解释你的第二列的范围和语义,这样你就可以确保正则表达式定期匹配它。

我构建了一个与您提供的数据并行的正则表达式,因此它可能与未来的传入行不匹配。正则表达式在这里:https://regex101.com/r/seLgca/2/ 它的作用是捕获三个主要组:

(.+?)\s?([a-z]?\d(?:\.\d){1,2}(?:-[a-z])?)?\s(abc|mnp)

让我们把正则表达式分成几部分:

  1. (.+?)
  2. \s?
  3. ([a-z]?\d(?:.\d){1,2}(?:-[a-z])?)?
  4. \s
  5. (abc|mnp)

以相反的顺序开始,第五部分只是匹配 abc 或 mnp。第四部分需要一个空格。第三部分匹配您的第二列(如果存在),请注意,这部分是您提供的内容,因此您可以修改此部分以更好地适应您的数据。第二部分需要一个空格(如果存在),这是因为行包含空的第二列。第一部分是其余部分。

据我所知,在 Oracle 中,我们有使用正则表达式的搜索和子字符串函数。因此,您需要一种编程语言来捕捉这些群体。

为此我写了一个Java方法:

static List<String> getGroups(String content, String regex){

    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(content);

    List<String> groupsMatched = new ArrayList<String>();

    if(matcher.find()){
        for(int i=0; i<matcher.groupCount(); i++)               
            groupsMatched.add(matcher.group(i));

        return groupsMatched; 
    }else
        return null;
}

因此,如果我使用您提供的行调用该方法,如下所示:

for(String content : listOfContent){            

        List<String> groupsMatched = getGroups(content, regex);

        if(groupsMatched != null)           
            System.out.println(groupsMatched.get(1) + "\t" + groupsMatched.get(2) + "\t" + groupsMatched.get(3) );

    }

这是我所拥有的:

some example text here   x2.0.3-a   abc
some other example text  1.5        abc
another example text     0.1.4      mnp
some other example text  null       abc
another example text     null       mnp

希望这会有所帮助。

干杯,

【讨论】:

  • “据我所知,在 Oracle 中,我们有使用正则表达式的搜索和子字符串函数”——您的意思是说“我们没有有”吗?跨度>
  • 甲骨文有REGEXP_SUBSTR()
  • 当我说“据我所知,我们有使用正则表达式的搜索和子字符串函数”时,我的意思是我们有 REGEXP_LIKE()、REGEXP_INSTR()、REGEXP_REPLACE() 和 REGEXP_SUBSTR() 函数。我没有使用任何否定。但是,如果想获得匹配模式的组,我不知道Oracle中是否有办法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
相关资源
最近更新 更多