【问题标题】:Regex Must Match a Word (not to replace) AND a Pattern (to replace) in a Line正则表达式必须匹配一行中的一个单词(不替换)和一个模式(替换)
【发布时间】:2022-01-26 23:14:58
【问题描述】:

使用正则表达式(可以是 PCRE 或 SED,但也可以是 python[请指定]),我想删除所有出现的包含单个字母逗号 (/,.,/g) 和单词“标签:”的行

例如在这些行中:

Labels: K,ltemittel,System,j,Vakuum,s
Another tags: a,b,xxx,c,yyy,z

Labels: ltemittel,System,Vakuum
Another tags: a,b,xxx,c,yyy,z

我尝试过的:

  • 非捕获组(“标签:”仍然被替换)
  • lookahead and lookbehind(不能使用贪心)
  • 分组/(Labels:)*(,.,)(也捕获非“标签:”)

【问题讨论】:

  • 这意味着任何一种方式都可以,在答案中可以指定他们使用的正则表达式风格。它可能对其他人有用。我将删除服务器,因为它含糊不清。感谢您指出这一点。

标签: python regex string sed pcre


【解决方案1】:

您可能会使用:

(?i)(^(?!Labels:).*)|\b[a-z],|,[a-z]\b

在线查看demo


  • (?i) - 设置不区分大小写的匹配“on”;
  • ( - 打开第一个捕获组;
    • ^ - 开始字符串锚点;
    • (?!labels:) - 断言位置后面没有“标签:”;
    • .* - 匹配(贪婪)除换行符以外的 0+ 个字符;
    • ) - 关闭第一个捕获组;
  • | - 或者;
  • \b[a-z], - 匹配单词边界,后跟单个字母和逗号;
  • | - 或者;
  • ,[a-z]\b - 匹配逗号后跟单个字母和单词边界。

现在替换你的1st捕获组。

【讨论】:

    【解决方案2】:

    使用sed

    $ sed '/Labels:/s/,[A-Za-z]\>//g;s/\<[A-Za-z],//' input_file
    Labels: ltemittel,System,Vakuum
    Another tags: a,b,xxx,c,yyy,z
    

    说明(由 Tripleee 添加)

    它查找逗号,后跟字母,然后是单词边界,即逗号后面的标签是单个字母。然后,它通过类似的逻辑删除逗号之前的所有剩余单字母标签

    【讨论】:

    • 谢谢,这个可以,但是你能对语法做更多解释吗?
    • 它查找逗号,后跟字母,然后是单词边界,即逗号后面的标签是单个字母。然后,它通过类似的逻辑删除逗号之前的所有剩余单字母标签。
    • @Ardhi 请检查编辑。三胞胎,谢谢:)
    【解决方案3】:

    使用gnu-awk 的另一个变体。

    对于以Labels: 开头的行,替换逗号,后跟单个字符 a-z 或 A-Z,并将单词边界替换为空字符串。

    awk '/^Labels:/{gsub(/,[a-zA-Z]\y|\y[a-zA-Z],/, "")};1' file
    

    输出

    Labels: ltemittel,System,Vakuum
    Another tags: a,b,xxx,c,yyy,z
    

    由于您已标记 Python 和 pcre,另一种选择是使用 \G 锚点并匹配字符串开头的 Label:,并在第 1 组中捕获您想要保留的内容。

    (?:^Labels:\h*|\G(?!^))\K(?:([^\s,]{2,}(?:,(?![a-z]$))?)|,?[a-z],?)
    

    使用 Python 查看regex demoPython demo PyPi regex module

    【讨论】:

      【解决方案4】:

      这可能对你有用(GNU sed):

      sed -E '/Labels/{s/( )\S,|(,)\S,|,\S$/\1\2/g;s//\1\2/g}' file
      

      如果一行包含Labels,则进行 3 个备用匹配的模式匹配,并且如果第一个和第二个匹配替换为匹配的反向引用。重复任何重叠。

      【讨论】:

        【解决方案5】:

        使用

        perl -lpe 's/(?:,[^,](?=,|$))+//g  if  s/^Labels:\s*\K(?:[^,](?:,|$))*//' file
        

        匹配“标签:”(即\Kept)后,删除所有前导单字符项。如果发生这种情况,请删除所有其他单字符项目。这假定“标签:”部分不能包含用逗号分隔的单个字符。

        $ cat file
        Labels: K,ltemittel,a System z,j,Vakuum,s
        Another tags: a,b,xxx,c,yyy,z
        $ perl -lpe 's/(?:,[^,](?=,|$))+//g  if  s/^Labels:\s*\K(?:[^,](?:,|$))*//' file
        Labels: ltemittel,a System z,Vakuum
        Another tags: a,b,xxx,c,yyy,z
        

        注意:System 在上述测试中被更改为a System z。依赖匹配空格或单词边界的解决方案可能无法正确处理此输入。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-03
          • 1970-01-01
          • 2012-09-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多