【问题标题】:Splitting course strings via regular expression通过正则表达式拆分课程字符串
【发布时间】:2017-02-20 15:33:17
【问题描述】:

大学的课程名称通常分为两个不同的部分,“部门”和“课程编号”

以英语 101 为例。

我的目标是编写一个与模式匹配的正则表达式,其中包含允许我指定查看前半部分还是后半部分的组。

问题在于,并非所有大学都对这些内容使用相同的格式。以下是我在其他大学遇到的“奇怪的东西”的 3 个测试用例。

1250-101
ENGLISH101
ENG|101-L

我写了 2 个正则表达式,一个处理所有奇怪的数字和奇数字符,一个处理从字母到数字的变化。但我无法想出一种方法让他们彼此很好地玩耍。我在下面复制了它们。

SELECT REGEXP_SUBSTR('ENGLISH101','(^\D*)(\d*)',1,1,NULL,1) FROM DUAL;
ENGLISH
SELECT REGEXP_SUBSTR('ENGLISH101','(^\D*)(\d*)',1,1,NULL,2) FROM DUAL;
101
SELECT REGEXP_SUBSTR('ENG|101-L','^(\w*)[\|/, \\-](.*)',1,1,NULL,1) FROM DUAL;
ENG
SELECT REGEXP_SUBSTR('ENG|101-L','^(\w*)[\|/, \\-](.*)',1,1,NULL,2) FROM DUAL;
101-L

所以这很好。但我不知道如何结合起来给我一个单一的正则表达式,这将使我能够根据分组获得英语(或其他任何东西)或 101。或者也许分组是导致这种头痛开始的原因?

或者,正则表达式一直都是错误的方法,我是否应该编写一个函数来逐个字符地遍历字符串并自己拆分它们?这似乎效率低下,但在这一点上我想我应该问这个问题。

对此的任何建议或见解将不胜感激。

【问题讨论】:

    标签: regex string plsql


    【解决方案1】:

    下面的查询应该选择与您描述的三个边缘情况对应的所有记录,并将课程名称的前半部分与后半部分分开。

    SELECT SUBSTR(col, 1, INSTR(col, '-') - 1) AS first_half,
           SUBSTR(col, INSTR(col, '-') + 1)    AS second_half
    FROM yourTable
    WHERE col LIKE '%-%' AND col NOT LIKE '%|%'
    UNION ALL
    SELECT SUBSTR(col, 1, INSTR(col, '|') - 1),
           SUBSTR(col, INSTR(col, '|') + 1)
    FROM yourTable
    WHERE col LIKE '%|%'
    UNION ALL
    SELECT REGEXP_REPLACE(col, '[0-9]', ''),
           REGEXP_REPLACE(col, '[A-Za-z]', '')
    FROM yourTable
    WHERE col NOT LIKE '%-%' AND col NOT LIKE '%|%'
    

    说明:

    UNION 中的第一个查询针对具有破折号但不是管道的课程名称。在这种情况下,我们可以根据破折号干净地拆分名称。第二个查询使用管道(也可以有破折号)定位名称。在这种情况下,我们要在管道上拆分。最后,第三个查询是剩下的情况,它是紧接在前面的字母课程名称,没有空格,是课程编号。为此,我使用REGEXP_REPLACE() 删除了数字或字母字符,将前半部分和后半部分留给我们。

    注意:如果您有边缘情况和正常数据,那么您可能需要稍微调整WHERE 条件。例如,要针对第三种边缘情况 ENGLISH101,您可能会检查它没有任何竖线或破折号,它没有空格,并且它有数字和字母。

    【讨论】:

    • 因此,如果我的理解正确,您建议使用各种选择语句(每个用例一个),它们只会对以他们知道如何解析的方式格式化的行进行操作,并且然后将这些结果合并在一起得到一个结果集?
    • @user3641364 这正是我的策略。问题是,要在单个正则表达式中执行此操作需要 AFAIK、前瞻或后视,无论如何都不支持。所以使用更基本的字符串函数可能是唯一的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多