Matchdata不返回与扫描相同的数据集

时间:2016-09-28 03:31:21

标签: ruby regex

给出以下文字:

text = '<w:body><w:p
w14:paraId="56037BEC" w14:textId="3419ABF1" w:rsidR="001665B3"
w:rsidRDefault="008B4AC6"><w:r><w:t xml:space="preserve">This is the
story of a man who </w:t></w:r><w:ins w:id="0" w:author="Mitchell Gou"
w:date="2016-09-28T09:15:00Z"><w:r
w:rsidR="003566BF"><w:t>went</w:t></w:r></w:ins><w:del w:id="1"
w:author="Mitchell Gou" w:date="2016-09-28T09:15:00Z"><w:r
w:rsidDel="003566BF"><w:delText>goes</w:delText></w:r></w:del><w:r><w:t
xml:space="preserve"> to the store to </w:t></w:r><w:ins w:id="2"
w:author="Mitchell Gou" w:date="2016-09-28T09:15:00Z"><w:r
w:rsidR="003566BF"><w:t>purchase</w:t></w:r></w:ins><w:del w:id="3"
w:author="Mitchell Gou" w:date="2016-09-28T09:15:00Z"><w:r
w:rsidDel="003566BF"><w:delText>buy</w:delText></w:r></w:del><w:r><w:t
xml:space="preserve"> some milk.</w:t></w:r><w:r w:rsidR="008C3761"><w:t
xml:space="preserve"> The was a </w:t></w:r><w:ins w:id="4"
w:author="Mitchell Gou" w:date="2016-09-28T09:18:00Z"><w:r
w:rsidR="008C3761"><w:t>replace</w:t></w:r></w:ins><w:del w:id="5"
w:author="Mitchell Gou" w:date="2016-09-28T09:18:00Z"><w:r
w:rsidR="008C3761"
w:rsidDel="008C3761"><w:delText>reason</w:delText></w:r></w:del><w:r
w:rsidR="008C3761"><w:t xml:space="preserve"> to remove the milk that
was already inside the man’s house.</w:t></w:r><w:r
w:rsidR="009D3E86"><w:t xml:space="preserve"> He wanted to
re</w:t></w:r><w:ins w:id="6" w:author="Mitchell Gou"
w:date="2016-09-28T09:22:00Z"><w:r
w:rsidR="009D3E86"><w:t>place</w:t></w:r></w:ins><w:bookmarkStart
w:id="7" w:name="_GoBack"/><w:bookmarkEnd w:id="7"/><w:del w:id="8"
w:author="Mitchell Gou" w:date="2016-09-28T09:22:00Z"><w:r
w:rsidR="009D3E86"
w:rsidDel="009D3E86"><w:delText>store</w:delText></w:r></w:del><w:r
w:rsidR="009D3E86"><w:t xml:space="preserve"> the
milk.</w:t></w:r></w:p><w:sectPr w:rsidR="001665B3"
w:rsidSect="00521CD0"><w:pgSz w:w="11900" w:h="16840"/><w:pgMar
w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708"
w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid
w:linePitch="360"/></w:sectPr></w:body>'

使用以下正则表达式:

scan_result = text.scan(/<w:ins.+?w:rsidR="([A-Z0-9]+)".+?<w:t>(\w+).+?w:rsidDel="([A-Z0-9]+)".+?<w:delText>(\w+)/m)

我得到以下结果:

[["003566BF", "went", "003566BF", "goes"], ["003566BF", "purchase", "003566BF", "buy"], ["008C3761", "replace", "008C3761", "reason"], ["009D3E86", "place", "009D3E86", "store"]]

但是,使用matchdata不会返回相同的数据集:

/<w:ins.+?w:rsidR="(?<sentence_id>[A-Z0-9]+)".+?<w:t>(\w+).+?w:rsidDel="([A-Z0-9]+)".+?<w:delText>(\w+)/m.match(text)

返回:

<w:ins w:id="0" w:author="Mitchell Gould"
w:date="2016-09-28T09:15:00Z"><w:r
w:rsidR="003566BF"><w:t>went</w:t></w:r></w:ins><w:del w:id="1"
w:author="Mitchell Gould" w:date="2016-09-28T09:15:00Z"><w:r
w:rsidDel="003566BF"><w:delText>goes

它似乎与所有数据都不匹配。这是为什么?

1 个答案:

答案 0 :(得分:1)

From Ruby docs

  

注意:正则表达式不能同时使用命名反向引用和编号反向引用。

scanmatch之间没有区别;你正在使用不同的正则表达式。在第二个正则表达式中,(?<sentence_id>...)是唯一的捕获,因为(...)无法正常工作。

强制性说明:如果您使用Nokogiri,Oga,REXML或任何其他XML解析引擎,而不是正则表达式,这将会更容易。

编辑:

re = /<w:ins.+?w:rsidR="([A-Z0-9]+)".+?<w:t>(\w+).+?w:rsidDel="([A-Z0-9]+)".+?<w:delText>(\w+)/m

text.scan(re)
# => [["003566BF", "went", "003566BF", "goes"], ["003566BF", "purchase", "003566BF", "buy"], ["008C3761", "replace", "008C3761", "reason"], ["009D3E86", "place", "009D3E86", "store"]] 

re.match(text)
# => #<MatchData "<w:ins w:id=\"0\" w:author=\"Mitchell Gou\"\nw:date=\"2016-09-28T09:15:00Z\"><w:r\nw:rsidR=\"003566BF\"><w:t>went</w:t></w:r></w:ins><w:del w:id=\"1\"\nw:author=\"Mitchell Gou\" w:date=\"2016-09-28T09:15:00Z\"><w:r\nw:rsidDel=\"003566BF\"><w:delText>goes" 1:"003566BF" 2:"went" 3:"003566BF" 4:"goes">

re.match(text).captures
# => ["003566BF", "went", "003566BF", "goes"]

[].tap { |r|
  p = 0
  while m = re.match(text, p)
    r << m.captures
    p = m.end(0)
  end
}
# => [["003566BF", "went", "003566BF", "goes"], ["003566BF", "purchase", "003566BF", "buy"], ["008C3761", "replace", "008C3761", "reason"], ["009D3E86", "place", "009D3E86", "store"]]