【问题标题】:Capture last occurrence from multiple occurrences in Regex pattern从正则表达式模式中的多次出现中捕获最后一次出现
【发布时间】:2021-09-19 12:24:28
【问题描述】:

如何捕获以下所需的捕获?我这样做了 Regex ONE.*(ONE.) 但它捕获了整个字符串。

记事本++:

1 ONE;TWO;THREE;ONE;FOUR;FIVE
2 TEST
3 TEST
4 TEST
5 TEST

所需捕获:如果 ONE 有 1 个匹配项,则返回 ONE;TWO;THREE,否则如果 ONE 有两个匹配项,则返回 ONE;FOUR;FIVE

【问题讨论】:

  • 嗨@Ryszard Czech,非常感谢你的回复,你能把它转换成regexpal.com吗?它在与我正在使用的兼容的正则表达式中不起作用……谢谢。
  • 从下拉框中选择 PCRE 选项。
  • 嗨@Ryszard Czech 是的,当我更改为 PCRE 时它可以工作,但是当我在 Toad SQL 中执行该模式时,它不起作用,我不知道为什么? SELECT REGEXP_SUBSTR(Column,' .*\KONE(?:(?!ONE).)*') as NML from tbl
  • 试试SELECT REGEXP_SUBSTR(Column, '.*(ONE.*)', 1, 1, NULL, 1)
  • 嗨,Ryszard Czech,它有效。谢谢。

标签: regex oracle toad


【解决方案1】:

你可以使用

^.*\K\bONE\b.*

模式匹配:

  • ^ 字符串开始
  • .* 匹配任意字符 0+ 次
  • \K\bONE\b 忘记到目前为止匹配的内容,并回溯到最后一次出现 ONE 以匹配它
  • .* 匹配该行的其余部分

Regex demo

【讨论】:

  • 嗨@第四只鸟,谢谢。但它不适用于regexpal.com
  • @MitchelAraw 您必须在右上角的下拉框中选择 PCRE。还可以选择多行以查看所有匹配项。
  • 如果 OP 正确使用了Oracle 标签、Oracle doesn't support\K\b 和许多其他有用的元字符。
【解决方案2】:

在 Toad SQL 中,使用

SELECT REGEXP_SUBSTR(Column, '.*(ONE.*)', 1, 1, NULL, 1)

解释

--------------------------------------------------------------------------------
  .*                       any character except \n (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    ONE                      'ONE'
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
  )                        end of \1

在记事本++中,使用

.*\KONE(?:(?!ONE).)*

regex proof

解释

--------------------------------------------------------------------------------
  .*                       any character except \n (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  \K                       matc reset operator
--------------------------------------------------------------------------------
  ONE                      'ONE'
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (0 or more times
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      ONE                      'ONE'
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    .                        any character except \n
--------------------------------------------------------

【讨论】:

    【解决方案3】:

    您也可以使用(?:ONE.*)?(ONE.*) 并从第一个捕获组中检索您的结果。

    此正则表达式将始终尝试匹配一行中的两个 ONE,但允许您访问与第二个 ONE 相关的部分。当只有一个是唯一匹配的部分时。

    你可以try it here

    【讨论】:

    • 嗨亚伦,分隔符“;”的数量是常数它总是 5 (;) 我们怎么称呼它说第三个分隔符的值?
    • 忽略 ONE,^[^;]*;[^;]*;([^;]*); 将在其第一个捕获组中具有第三个字段的值
    • 谢谢你亚伦它的作品。
    • 嗨@Aaron我更喜欢你的模式如果有50个(;)我该如何改写模式并且我想在第30个(;)的某个地方捕获而不做^ [^;] *; 30 次?
    • 您可以分解前 29 个字段:^(?:[^;]*;){29}([^;]*)
    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多