【问题标题】:Regex to find multiple matches in between two strings正则表达式在两个字符串之间查找多个匹配项
【发布时间】:2016-05-01 22:50:20
【问题描述】:

这里是我正在尝试执行正则表达式的字符串的链接:http://pastebin.com/raw/TRKbqGxs

是的,我知道正则表达式不是解析 HTML 的最佳选择,但我想在这个项目中使用它。我暂时不想使用 HTML 能力包。

我的主要兴趣是这样的行:

data-screen-name="thanhbach195" data-name="Mai Thanh Bách" data-protected="false">

data-screen-name="zeref980" data-name="Yan Naung Htet" data-protected="false">

我想导出以下文本块 data-screen-name="" data-name= 之间的数据。

基本上,在这种情况下thanhbach195zeref980

我尝试了以下正则表达式:string reg = "data-screen-name=\"(.*)\" data-name=\"";

但由于某种原因,我没有得到多场比赛的答案。事实上,它似乎根本没有提取我想要的字符串。

如果有人可以帮助我编写一个正确的正则表达式来提取我上面上传的字符串中这两个字符串之间的所有匹配项,我将不胜感激。

private List<string> getUsers(string str)
        {
            List<string> users = new List<string>();
            string reg = "data-screen-name=\"(.*)\" data-name=\"";
            MatchCollection mc = Regex.Matches(str, reg);
            foreach(Match m in mc)
            {
                users.Add(m.Groups[1].Value);
            }
            return users;
        }

这段代码每次都返回相同的匹配项(我相信是第一个)。

【问题讨论】:

  • 您应该为此使用 Html Agility Pack。但你已经知道了。
  • 但它工作正常。 (i.stack.imgur.com/PN5bJ.png)。你是如何获取团队价值的?您的 html 中是否有多个匹配项?
  • 是的@MaximilianGerhardt 有超过 1 个匹配项,这是我的问题。
  • @RobertHarvey 我同意,但我想在我现在正在编写的这个软件中使用正则表达式。 Html Agility Pack 确实让它变得更容易了。
  • 我必须一再补充:不要使用点匹配模式来解析分隔文本。使用否定字符类,有时使用交替。

标签: c# regex string


【解决方案1】:

免责声明

您应该真正使用 HTML 解析引擎,因为正则表达式无法轻松适应许多模糊的边缘情况。但我不是你的妈妈,所以我不会告诉你如何过你的生活。

由于您似乎可以控制源文本,因此您可能能够完全避免晦涩的边缘情况。

说明

此正则表达式将执行以下操作:

  • 找到所有div标签
  • 确保找到的每个 div 标记都包含一个 class="user-actions 带或不带引号
  • data-screen-namedata-namedata-protected 的值捕获到它们自己的捕获组中
  • 允许属性/值集以任意顺序出现
  • 允许值周围的引号是可选的,因此您可以使用单引号、双引号或不使用引号
  • 从值中删除引号,以便获得原始值
  • 避免了匹配 HTML 时正则表达式警察所抱怨的许多混乱边缘情况

正则表达式

&lt;div\b(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?class=['"]?user-actions)(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?data-screen-name=(['"]?)(.*?)\1(?:\s|&gt;))(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?data-name=(['"]?)(.*?)\3(?:\s|&gt;))(?=(?:[^&gt;=]|='[^']*'|="[^"]*"|=[^'"][^\s&gt;]*)*?data-protected=(['"]?)(.*?)\5(?:\s|&gt;))(?:[^&gt;=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s&gt;]*)*\s*&gt;

我建议使用不区分大小写的标志。

示例

摘自原文

示例文本的一小部分

<div class="user-actions btn-group not-following not-muting protected" data-user-id="726459723365502976"
data-screen-name="Just__Kidding__" data-name="Chaw Chin Fong" data-protected="true">

现场示例

只显示整个文件的较大部分,因为在线工具会被大量文本字符串所困扰。

https://regex101.com/r/bY1kH8/1

捕获组

  • 第 0 组获取整个开始 div 标记
  • 如果data-screen-name 值周围有一个报价,则为第 1 组获取分配报价
  • 第 2 组获取 data-screen-name 值,不包括任何引号
  • 如果data-name 值周围有一个引用,则为第 3 组获取分配引用
  • 第 4 组获取 data-name 值,不包括任何引号
  • 如果data-protected 值周围有一个报价,则为第 5 组获取分配报价
  • 第 6 组获取 data-protected 值,不包括任何引号

示例匹配

这些是使用建议的正则表达式从您的源文本中提取的。

[0][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="2582252852"
        data-screen-name="w33haa" data-name="Aliwi Omar" data-protected="false">
[0][1] = "
[0][2] = w33haa
[0][3] = "
[0][4] = Aliwi Omar
[0][5] = "
[0][6] = false

[1][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="1680222842"
        data-screen-name="Jamjomon" data-name="Jamchu :3" data-protected="false">
[1][1] = "
[1][2] = Jamjomon
[1][3] = "
[1][4] = Jamchu :3
[1][5] = "
[1][6] = false

[2][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="1523823648"
        data-screen-name="dimakoza4enko" data-name="Дима Козаченко" data-protected="false">
[2][1] = "
[2][2] = dimakoza4enko
[2][3] = "
[2][4] = Дима Козаченко
[2][5] = "
[2][6] = false

[3][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="1522238240"
        data-screen-name="alupulipulipala" data-name="Wahid Arefin" data-protected="false">
[3][1] = "
[3][2] = alupulipulipala
[3][3] = "
[3][4] = Wahid Arefin
[3][5] = "
[3][6] = false

[4][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="4804204573"
        data-screen-name="thanhbach195" data-name="Mai Thanh Bách" data-protected="false">
[4][1] = "
[4][2] = thanhbach195
[4][3] = "
[4][4] = Mai Thanh Bách
[4][5] = "
[4][6] = false

[5][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="726465523223908353"
        data-screen-name="zeref980" data-name="Yan Naung Htet" data-protected="false">
[5][1] = "
[5][2] = zeref980
[5][3] = "
[5][4] = Yan Naung Htet
[5][5] = "
[5][6] = false

[6][0] = <div class="user-actions btn-group not-following not-muting protected" data-user-id="726459723365502976"
        data-screen-name="Just__Kidding__" data-name="Chaw Chin Fong" data-protected="true">
[6][1] = "
[6][2] = Just__Kidding__
[6][3] = "
[6][4] = Chaw Chin Fong
[6][5] = "
[6][6] = true

[7][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="713605605638938624"
        data-screen-name="Fruitcentre" data-name="Fruit &amp; Veg Centre" data-protected="false">
[7][1] = "
[7][2] = Fruitcentre
[7][3] = "
[7][4] = Fruit &amp; Veg Centre
[7][5] = "
[7][6] = false

[8][0] = <div class="user-actions btn-group not-following not-muting protected" data-user-id="555968644"
        data-screen-name="aeronhalecastle" data-name="Eywon ツ" data-protected="true">
[8][1] = "
[8][2] = aeronhalecastle
[8][3] = "
[8][4] = Eywon ツ
[8][5] = "
[8][6] = true

[9][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="2845398050"
        data-screen-name="Deheyb" data-name="4k Scrub✌️" data-protected="false">
[9][1] = "
[9][2] = Deheyb
[9][3] = "
[9][4] = 4k Scrub✌️
[9][5] = "
[9][6] = false

[10][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="721815663216566272"
        data-screen-name="Ribbon2712" data-name="Даниил Демидов" data-protected="false">
[10][1] = "
[10][2] = Ribbon2712
[10][3] = "
[10][4] = Даниил Демидов
[10][5] = "
[10][6] = false

[11][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="3248438456"
        data-screen-name="zayarmgmg95" data-name="Zayar Mg" data-protected="false">
[11][1] = "
[11][2] = zayarmgmg95
[11][3] = "
[11][4] = Zayar Mg
[11][5] = "
[11][6] = false

[12][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="726440286063198208"
        data-screen-name="Ninderpy" data-name="Derpy" data-protected="false">
[12][1] = "
[12][2] = Ninderpy
[12][3] = "
[12][4] = Derpy
[12][5] = "
[12][6] = false

[13][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="423763655"
        data-screen-name="ImJoehuff" data-name="JoeyT" data-protected="false">
[13][1] = "
[13][2] = ImJoehuff
[13][3] = "
[13][4] = JoeyT
[13][5] = "
[13][6] = false

[14][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="726441786839703556"
        data-screen-name="zxmir_" data-name="Zxmir_" data-protected="false">
[14][1] = "
[14][2] = zxmir_
[14][3] = "
[14][4] = Zxmir_
[14][5] = "
[14][6] = false

[15][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="726440845713367041"
        data-screen-name="hienlequang" data-name="Hiền Lê Quang" data-protected="false">
[15][1] = "
[15][2] = hienlequang
[15][3] = "
[15][4] = Hiền Lê Quang
[15][5] = "
[15][6] = false

[16][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="3032113115"
        data-screen-name="Najer14" data-name="Jan" data-protected="false">
[16][1] = "
[16][2] = Najer14
[16][3] = "
[16][4] = Jan
[16][5] = "
[16][6] = false

[17][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="4762819022"
        data-screen-name="7forOne" data-name="Abiel" data-protected="false">
[17][1] = "
[17][2] = 7forOne
[17][3] = "
[17][4] = Abiel
[17][5] = "
[17][6] = false

[18][0] = <div class="user-actions btn-group not-following not-muting " data-user-id="717061680799330306"
        data-screen-name="Th3uN1qu31" data-name="Th3_uN1Qu3" data-protected="false">
[18][1] = "
[18][2] = Th3uN1qu31
[18][3] = "
[18][4] = Th3_uN1Qu3
[18][5] = "
[18][6] = false

解释

NODE                     EXPLANATION
----------------------------------------------------------------------
  <div                     '<div'
----------------------------------------------------------------------
  \b                       the boundary between a word char (\w) and
                           something that is not a word char
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the least amount
                             possible)):
----------------------------------------------------------------------
      [^>=]                    any character except: '>', '='
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ='                       '=\''
----------------------------------------------------------------------
      [^']*                    any character except: ''' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      '                        '\''
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ="                       '="'
----------------------------------------------------------------------
      [^"]*                    any character except: '"' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      "                        '"'
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      =                        '='
----------------------------------------------------------------------
      [^'"]                    any character except: ''', '"'
----------------------------------------------------------------------
      [^\s>]*                  any character except: whitespace (\n,
                               \r, \t, \f, and " "), '>' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
    )*?                      end of grouping
----------------------------------------------------------------------
    class=                   'class='
----------------------------------------------------------------------
    ['"]?                    any character of: ''', '"' (optional
                             (matching the most amount possible))
----------------------------------------------------------------------
    user-actions             'user-actions'
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the least amount
                             possible)):
----------------------------------------------------------------------
      [^>=]                    any character except: '>', '='
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ='                       '=\''
----------------------------------------------------------------------
      [^']*                    any character except: ''' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      '                        '\''
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ="                       '="'
----------------------------------------------------------------------
      [^"]*                    any character except: '"' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      "                        '"'
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      =                        '='
----------------------------------------------------------------------
      [^'"]                    any character except: ''', '"'
----------------------------------------------------------------------
      [^\s>]*                  any character except: whitespace (\n,
                               \r, \t, \f, and " "), '>' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
    )*?                      end of grouping
----------------------------------------------------------------------
    data-screen-name=        'data-screen-name='
----------------------------------------------------------------------
    (                        group and capture to \1:
----------------------------------------------------------------------
      ['"]?                    any character of: ''', '"' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
    )                        end of \1
----------------------------------------------------------------------
    (                        group and capture to \2:
----------------------------------------------------------------------
      .*?                      any character (0 or more times
                               (matching the least amount possible))
----------------------------------------------------------------------
    )                        end of \2
----------------------------------------------------------------------
    \1                       what was matched by capture \1
----------------------------------------------------------------------
    (?:                      group, but do not capture:
----------------------------------------------------------------------
      \s                       whitespace (\n, \r, \t, \f, and " ")
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      >                        '>'
----------------------------------------------------------------------
    )                        end of grouping
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the least amount
                             possible)):
----------------------------------------------------------------------
      [^>=]                    any character except: '>', '='
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ='                       '=\''
----------------------------------------------------------------------
      [^']*                    any character except: ''' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      '                        '\''
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ="                       '="'
----------------------------------------------------------------------
      [^"]*                    any character except: '"' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      "                        '"'
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      =                        '='
----------------------------------------------------------------------
      [^'"]                    any character except: ''', '"'
----------------------------------------------------------------------
      [^\s>]*                  any character except: whitespace (\n,
                               \r, \t, \f, and " "), '>' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
    )*?                      end of grouping
----------------------------------------------------------------------
    data-name=               'data-name='
----------------------------------------------------------------------
    (                        group and capture to \3:
----------------------------------------------------------------------
      ['"]?                    any character of: ''', '"' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
    )                        end of \3
----------------------------------------------------------------------
    (                        group and capture to \4:
----------------------------------------------------------------------
      .*?                      any character (0 or more times
                               (matching the least amount possible))
----------------------------------------------------------------------
    )                        end of \4
----------------------------------------------------------------------
    \3                       what was matched by capture \3
----------------------------------------------------------------------
    (?:                      group, but do not capture:
----------------------------------------------------------------------
      \s                       whitespace (\n, \r, \t, \f, and " ")
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      >                        '>'
----------------------------------------------------------------------
    )                        end of grouping
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the least amount
                             possible)):
----------------------------------------------------------------------
      [^>=]                    any character except: '>', '='
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ='                       '=\''
----------------------------------------------------------------------
      [^']*                    any character except: ''' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      '                        '\''
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      ="                       '="'
----------------------------------------------------------------------
      [^"]*                    any character except: '"' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
      "                        '"'
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      =                        '='
----------------------------------------------------------------------
      [^'"]                    any character except: ''', '"'
----------------------------------------------------------------------
      [^\s>]*                  any character except: whitespace (\n,
                               \r, \t, \f, and " "), '>' (0 or more
                               times (matching the most amount
                               possible))
----------------------------------------------------------------------
    )*?                      end of grouping
----------------------------------------------------------------------
    data-protected=          'data-protected='
----------------------------------------------------------------------
    (                        group and capture to \5:
----------------------------------------------------------------------
      ['"]?                    any character of: ''', '"' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
    )                        end of \5
----------------------------------------------------------------------
    (                        group and capture to \6:
----------------------------------------------------------------------
      .*?                      any character (0 or more times
                               (matching the least amount possible))
----------------------------------------------------------------------
    )                        end of \6
----------------------------------------------------------------------
    \5                       what was matched by capture \5
----------------------------------------------------------------------
    (?:                      group, but do not capture:
----------------------------------------------------------------------
      \s                       whitespace (\n, \r, \t, \f, and " ")
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      >                        '>'
----------------------------------------------------------------------
    )                        end of grouping
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
  (?:                      group, but do not capture (0 or more times
                           (matching the most amount possible)):
----------------------------------------------------------------------
    [^>=]                    any character except: '>', '='
----------------------------------------------------------------------
   |                        OR
----------------------------------------------------------------------
    ='                       '=\''
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the most amount
                             possible)):
----------------------------------------------------------------------
      [^']                     any character except: '''
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      \\                       '\'
----------------------------------------------------------------------
      '                        '\''
----------------------------------------------------------------------
    )*                       end of grouping
----------------------------------------------------------------------
    '                        '\''
----------------------------------------------------------------------
   |                        OR
----------------------------------------------------------------------
    ="                       '="'
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the most amount
                             possible)):
----------------------------------------------------------------------
      [^"]                     any character except: '"'
----------------------------------------------------------------------
     |                        OR
----------------------------------------------------------------------
      \\                       '\'
----------------------------------------------------------------------
      "                        '"'
----------------------------------------------------------------------
    )*                       end of grouping
----------------------------------------------------------------------
    "                        '"'
----------------------------------------------------------------------
   |                        OR
----------------------------------------------------------------------
    =                        '='
----------------------------------------------------------------------
    [^'"]                    any character except: ''', '"'
----------------------------------------------------------------------
    [^\s>]*                  any character except: whitespace (\n,
                             \r, \t, \f, and " "), '>' (0 or more
                             times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )*                       end of grouping
----------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
----------------------------------------------------------------------
  >                        '>'

【讨论】:

    【解决方案2】:

    尝试在下一个双引号处终止的非贪婪命名正则表达式,而不是贪婪匹配

    string reg = "data-screen-name=\"(?<dataScreenName>[^\"]+)\" data-name=\"(?<dataName>[^\"]+\"";
    

    这将允许您使用

    foreach(Match m in mc)
    {
        users.Add(m.Groups["dataScreenName"].Value);
    }
    

    【讨论】:

    • 显然,我错过了其他东西。正则表达式不是问题,因为它与我在问题中发布的相同。
    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 2012-09-26
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多