如何在Delphi中获取正则表达式的命名组?

时间:2013-12-24 21:38:22

标签: regex delphi

我正在尝试在Delphi上使用正则表达式来重新编写HTML并获取一些数据。

我的目标是使用以下sintax创建一个查询字符串:

?namedGroup1=valueNamedGroup1&namedGroup2=valueNamedGroup2

我有n个正则表达式数组:

array[0] = '<div (id="(?<id>[a-zA-Z0-9]+)"|name="(?<name>[a-zA-Z0-9]+))"';

我的HTML:

<h1>bla bla bla</h1> <div id="home">

如果我在PHP中使用内置的正则表达式应用此正则表达式,它将返回一个关联数组

RegArray[0] = '<div id="home">'
RegArray['id'] = 'home'

如果我做一个foreach,我很容易得到命名组的列表,我可以创建我的查询字符串:

?id=home

问题是我不知道正则表达式是否与命名的组ID或名称匹配,我需要知道。

Delphi只返回一个简单的数组

RegArray[0] = '<div id="home">'
RegArray[1] = 'home'  // ID or NAME?

那么,我如何获得命名组和命名组值?

这是我的代码:

var RegEx: TRegEx;
begin
 RegEx := TRegEx.Create(array[0], [roIgnoreCase,roMultiline]);
 Match := RegEx.Match(html);
 if (Match.Success) then
 begin
   //get the group here.
 end;

我也试过这堂课:http://www.regular-expressions.info/delphi.html

但没有成功

4 个答案:

答案 0 :(得分:2)

我认为你在查询中犯了一个错误:看看模式的最后两个字符 - 它显然是不平衡的!看起来你没能从PHP复制粘贴; - )

  • 你的:<div (id="(?<id>[a-zA-Z0-9]+)"|name="(?<name>[a-zA-Z0-9]+))"
  • 我的:<div (id="(?<id>[a-zA-Z0-9]+)"|name="(?<name>[a-zA-Z0-9]+)")

DI RegExp demo

使用http://www.yunqa.de/delphi/doku.php/products/regex/index

中的pcre.org引擎+交互式编辑器
  

我也试过这堂课:http://www.regular-expressions.info/delphi.html

该页面立即显示另一个可用于调试RegEx程序的交互式编辑器:http://www.regexbuddy.com/test.html

我想知道你为什么不试着用它......


我仍然认为一些HTML解析器会更快,更可靠。考虑像

这样的HTML提取
 <!-- <p><div name="bla-bla"> ... </div></p> -->

或喜欢

 <img src="...." alt='Press to insert <div id="123"> to you sample text' />

或喜欢

 <DIV ID="my cool id" />

主题入门者在下面做了他自己的答案,主要包括对我的问题。

  

问题不在于正则表达式,

只需用笔和纸计算引号和箭头,按顺序打开和关闭它们。你的模式是( ... " ... ) .... " - 它是不平衡的!

  

是德尔福。

Delphi语言与regexp没有任何关系。库/组件可以做到。所以这种说法毫无意义。你可能会说你测试了破坏的库,但没有测试语言本身。

  

我的PHP正则表达式正常,

这应该意味着要么你在PHP中有不同的正则表达式模式(你没有在这里复制PHP源代码)或“问题是在PHP中”

实际上我们既没有看到Delphi源也没有看到PHP源。

array[0] = '<div (id="(?<id>[a-zA-Z0-9]+)"|name="(?<name>[a-zA-Z0-9]+))"'; - 我认为两者都不正确。

所以我不认为PHP程序和Delphi程序中的代码和模式相互匹配。显示正在使用的实际代码的引用。

  事情是DELPHI没有回我

  1. 再一次,这只是没有感觉。 Delphi只是一种语言,它对RegEx不了解。
  2. 就在上方,您看到了使用PCRE引擎的Delphi编写程序的屏幕截图 - 鉴于已修复的模式,它会返回名称和值。因此即使在模糊的意义上,这种说法显然是错误的。德尔福为它返回<name, value>对。
  3.   

    另外,我无法改变整个系统使用HTML解析器,正则表达式已经正常工作

    然后你需要调整正则表达式来正确解析我上面显示的HTML片段。

答案 1 :(得分:1)

TRegEx(来自System.RegularExpressions)是TPerlRegEx(来自System.RegularExpressionsCore)的包装,它是开源PCRE library的包装。

PCRE当然支持检索组的名称,但是两个包装器都不支持。

可能的解决方案:

  • 要求Embarcadero进行修复
  • 直接访问PCRE(System.RegularExpressionsAPI
  • 使用两个包装器之一,但是要检索名称,请侵入其私有成员以访问PCRE内存(pcre_fullinfo(TPerlRegEx.FPattern, ...)
  • 使用更好的包装,即来自开源JEDI Code Library(JCL)的JclPCREName1:= TJclRegEx.CaptureNames[1];

答案 2 :(得分:0)

Arioch,

问题不在于正则表达式,而是Delphi。

我的PHP正则表达式工作得很好,问题是DELPHI没有返回我捕获的组名,只返回我捕获的值。

另外,我不能改变整个系统使用HTML解析器,正则表达式已经工作,我需要在Delphi上进行这项工作。

答案 3 :(得分:0)

我不确定枚举命名组,但您可以通过索引或名称访问该组:

const
  cRegEx = '<div (id="(?<id>[a-zA-Z0-9]+)"|name="(?<name>[a-zA-Z0-9]+)")';
  cHtml = '<h1>bla bla bla</h1> <div id="home">';
var
  group: TGroup;
  match: TMatch;
  regEx: TRegEx;
begin
  regEx := TRegEx.Create(cRegEx, [roIgnoreCase,roMultiline]);
  match := regEx.Match(cHtml);
  if match.Success then begin
    group := match.Groups['id'];
    Assert(group.Value = 'home');
  end;
end;