仅使用 REGEX,将最后一个(分隔的)单词复制到每个逗号分隔的值?

仅使用 REGEX,将最后一个(分隔的)单词复制到每个逗号分隔的值?

我有一系列行,其中有任意数量的逗号分隔值,然后是一个井号标记的注释。挑战在于,使用仅有的 PCRE2正则表达式用于PERL,执行以下操作:

  • 存储‘##’后的短语
  • 在短语中添加管道
  • 从字符串末尾删除
  • 将此存储的短语复制到每个逗号分隔的值 (编辑:这可以是任意数量的 CSV)
  • 将逗号替换为“##”
  • 确保行末没有“##”或逗号

这是我的测试字符串:

quirky, stable, fun ##Paul and Jill  
mean, rude, sad ##Dave   
rich, foolish, gorgeous ##Amanda

期望的结果:

Paul and Jill|quirky##Paul and Jill|stable##Paul and Jill|fun  
Dave|mean##Dave|rude##Dave|sad  
Amanda|rich##Amanda|foolish##Amanda|gorgeous  

我正在使用 PCRE2 Regex 构建 PERL 搜索/替换字符串以用于 ExifTool。

此正则表达式代码:

(.+?)(?:,|##)

查找所有以逗号分隔的值,并将每个值作为单独的实例存储在组 1 中匹配三次后,直到达到井号。

与此同时,这:

(?<=##)(.*)|$

在“##”后面找到短语,这很棒!但是当我把它们放在一起时

(.+?)(?:,|##)(?<=##)(.*)|$

突然之间,第一组中用逗号分隔的值的单独实例变成了一个大组,所以我想要的(古怪)(稳定)(有趣)变成了(古怪,稳定,有趣),这对我来说没有用。

这没用的原因是因为替换不起作用。使用:

$2|$1

将会给予:

Paul and Jill|quirky, stable, fun"

但我想要:

Paul and Jill|quirky##Paul and Jill|stable##Paul and Jill|fun

**编辑:感谢@Toto,我将正则表达式修改为:^((\w+)\W+)*?(\w+)\h+(##(.+))$,这允许捕获任意数量的 CSV,但替换将是不可能的,因为它必须知道捕获了多少组,据我所知**

我认为如果每个匹配都是第一组的一个单独实例,那么可能有一种方法可以将井号后的第二组短语与第一组中的每个匹配进行匹配。

直观地讲,这对我来说是有意义的:“复制井号后的短语,然后用该短语的修改形式替换所有逗号”。

我不需要帮助修改短语,只需让示例文本正确解析即可。多步骤正则表达式解决方案也很好,我暂时不想优化它。

答案1

您的要求无法用 PCRE 风格来满足。

但是它可以与使用 BOOST 风格的 Notepad++ 一起使用:

  • Ctrl+H
  • 找什么:(?:^|\G(?!^))(?:(\w+),\h(?=.*##(.+)$)|(\w+)\h##(.+)$)
  • 用。。。来代替:(?2$2|$1##)(?3$4|$3)
  • 打钩 环绕
  • 选择 正则表达式
  • 取消勾选 . matches newline
  • Replace all

解释:

(?:             # non capture group
    ^               # beginning of line
  |               # OR
    \G              # restart from last match position
    (?!^)           # not at beginning of line
)               # end group
(?:             # non capture group
    (\w+)           # group 1, 1 or more word character
    ,               # comma
    \h              # horizontal space
    (?=             # positive lookahead, make sure we have after:
        .*              # 0 or more any character but newline
        ##              # literally
        (.+)            # group 2, 1 or more any character but newline
        $               # end of line
    )               # end lookahead
  |               # OR
    (\w+)           # group 3, 1 or more word character
    \h              # horizontal space
    ##              # literally
    (.+)            # group 4, 1 or more any character but newline
    $               # end of line
)               # end group

替代品:

(?2         # if group 2 exists
    $2          # print its content
    |           # with a pipe
    $1          # content of group 1
    ##          # literally
)           # end condition
(?3         # if group 3 exists
    $4          # print content of group 4  
    |           # a pipe
    $3          # content of group 3
)           # end condition

截图(之前):

在此处输入图片描述

截图(之后):

在此处输入图片描述

相关内容