【问题标题】:How can I extract a substring after a match position?如何在匹配位置后提取子字符串?
【发布时间】:2009-09-28 10:57:58
【问题描述】:

我需要从一个非常长的 line ed 文件中 grep 一个字符串或模式(比如在字符串或模式之前和之后大约 200 个字符)。该文件包含来自远程服务器并附加到文件的这一行的数据流(市场交易数据)。

我知道我可以使用grep(或其他工具)匹配包含特定模式的行,但是一旦我有了这样的行,我该如何提取行的一部分?我想用图案加上图案前后大约 200 个字符来抓取线条的一部分。我会对使用...的答案特别感兴趣(在此处提供您喜欢的工具或语言)。

【问题讨论】:

  • 那么你的问题到底是什么?
  • 告诉我们您的要求并列出一大堆潜在工具 (?) 甚至都不是问题。数据是什么样的?图案是什么样的?你试过什么?
  • 需要从线路及其周围环境中 grep 字符串(比如 "ASDF" )。希望我澄清了这个问题。
  • @Jtk:你真的没有。 grep 'ASDF' filename 应该按照你所说的来工作。 “从线路及其周围环境”是什么意思?你的意思是字符串必须出现在一行以及其他地方(?行附近?之前?之后?)才能成为热门?老实说,这很愚蠢。
  • 我很抱歉再次用环境这个词来呈现它。事实上,“ASDF”在长行中只出现一次,要求收集该字符串前后的 200 个字符(“ASDF”)。因为我问这个问题是因为 grep (与 xargs 一起)按预期提供了完整的行,这不是我想要的。谢谢。

标签: regex string


【解决方案1】:

如果您需要的是表达式前后的 200 个字符加上表达式本身,那么您正在查看:

/.{200}aaa.{200}/

如果您需要对每个部分进行捕获(允许您将每个部分提取为一个单元),那么您可以使用此正则表达式:

/(.{200})(aaa)(.{200})/

【讨论】:

    【解决方案2】:

    如果您的grep-o,那么它将只输出匹配的部分。

     echo "abc def ghi jkl mno pqr" | egrep -o ".{4}ghi.{4}"
    

    产生:

    def ghi jkl
    

    【讨论】:

      【解决方案3】:

      (.{0,200}(pattern).{0,200}),还是什么?

      【讨论】:

        【解决方案4】:

        这是您想要的(在 C 中)吗?
        如果是,请随时适应您的特定需求。

        #include <stdio.h>
        #include <string.h>
        
        void prt_grep(const char *haystack, const char *needle, int padding) {
          char *ptr, *start, *finish;
          ptr = strstr(haystack, needle);
          if (!ptr) return;
          start = (ptr - padding);
          if (start < haystack) start = haystack;
          finish = ptr + strlen(needle) + padding;
          if (finish > haystack + strlen(haystack)) finish = haystack + strlen(haystack);
          for (ptr = start; ptr < finish; ptr++) putchar(*ptr);
        }
        
        int main(void) {
          const char *longline = "123456789 ASDF 123456789";
          const char *pattern = "ASDF";
        
          prt_grep(longline, pattern, 5); /* you want 200 */
          return 0;
        }
        

        【讨论】:

        • 恭喜你,你重新发明了轮子!
        • 标准 C 库中是否有执行此操作的函数?在 POSIX C 库中?如果有,最好的选择是忽略我的回答并使用图书馆提供的解决方案。 [perl] [bash] [python] [php] [c] 是一大堆语言标签
        【解决方案5】:

        我想我可以通过匹配我需要的字符串部分来解决问题,然后使用匹配位置作为子字符串提取的起点。在 Perl 中,一旦你的正则表达式成功,内置的 pos 会告诉你你离开的地方:

         if( $long_string = m/$regex/ ) {
              $substring = substr( $long_string, pos( $long_string ), 200 );
              }
        

        我倾向于使用 Perl 编写程序,而不是使用正则表达式。在这种情况下,Perl 没有什么特别之处。

        【讨论】:

          【解决方案6】:

          我认为这可能是每个人都在想的更基本的内容,如果我错了,请纠正我...... 您要打印 beforeafter 字符串 排除 字符串吗?

          awk -F "ASDF" '{print "Before ASDF" $1 "\n" "After ASDF" $2}' $FILE

          这将打印如下内容:

          在 ASDF blablabla 之前

          在 ASDF blablablabla 之后

          更改它以满足您的需要,删除“\n”和/或“之前...”和“之后...”cmets

          您要抑制文件中的字符串吗? 这将用空格替换字符串,再次将其更改为您需要的任何内容。

          sed -i 's/ASDF/\ /' longstring.txt

          HTH

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-05-31
            • 2022-12-09
            • 2019-03-14
            • 1970-01-01
            • 1970-01-01
            • 2011-05-21
            • 2015-10-19
            • 2023-03-17
            相关资源
            最近更新 更多