ColdFusion,REGEX - 给定TEXT,查找SPAN中包含的所有项目

AnA*_*ice 2 regex coldfusion

我正在学习如何在Coldfusion中创建一个REGEX,它将扫描大量的html文本并创建一个项目列表.

我想要的项目包含在以下内容中

<span class="findme">The Goods</span>
Run Code Online (Sandbox Code Playgroud)

感谢任何提示,以实现这一目标.

Spl*_*iFF 6

你不说什么版本的CF. 从v8开始,您可以使用REMatch来获取数组

results = REMatch('(?i)<span[^>]+class="findme"[^>]*>(.+?)</span>', text)
Run Code Online (Sandbox Code Playgroud)

使用ArrayToList将其转换为列表.对于旧版本,使用REFindNoCase并使用Mid()来提取子字符串.

编辑:为了回答你的后续评论,使用REFind返回所有匹配的过程非常复杂,因为该函数只返回FIRST匹配.这意味着你每次都必须多次调用REFind传递一个新的startpos.Ben Forta已经编写了一个UDF,它正是这样做的,并且会节省你一些时间.

<!---
Returns all the matches of a regular expression within a string.
NOTE: Updated to allow subexpression selection (rather than whole match)

@param regex      Regular expression. (Required)
@param text       String to search. (Required)
@param subexnum   Sub-expression to extract (Optional)
@return Returns a structure.
@author Ben Forta (ben@forta.com)
@version 1, July 15, 2005
--->
<cffunction name="reFindAll" output="true" returnType="struct">
<cfargument name="regex" type="string" required="yes">
<cfargument name="text" type="string" required="yes">
<cfargument name="subexnum" type="numeric" default="1">

<!--- Define local variables --->    
<cfset var results=structNew()>
<cfset var pos=1>
<cfset var subex="">
<cfset var done=false>

<!--- Initialize results structure --->
<cfset results.len=arraynew(1)>
<cfset results.pos=arraynew(1)>

<!--- Loop through text --->
<cfloop condition="not done">

   <!--- Perform search --->
   <cfset subex=reFind(arguments.regex, arguments.text, pos, true)>
   <!--- Anything matched? --->
   <cfif subex.len[1] is 0>
      <!--- Nothing found, outta here --->
      <cfset done=true>
   <cfelse>
      <!--- Got one, add to arrays --->
      <cfset arrayappend(results.len, subex.len[arguments.subexnum])>
      <cfset arrayappend(results.pos, subex.pos[arguments.subexnum])>
      <!--- Reposition start point --->
      <cfset pos=subex.pos[1]+subex.len[1]>
   </cfif>
</cfloop>

<!--- If no matches, add 0 to both arrays --->
<cfif arraylen(results.len) is 0>
   <cfset arrayappend(results.len, 0)>
   <cfset arrayappend(results.pos, 0)>
</cfif>

<!--- and return results --->
<cfreturn results>
</cffunction>
Run Code Online (Sandbox Code Playgroud)

这为您提供了每个匹配的开始(pos)和长度,以便让每个子字符串使用另一个循环

<cfset text = '<span class="findme">The Goods</span><span class="findme">More Goods</span>' />
<cfset pattern = '(?i)<span[^>]+class="findme"[^>]*>(.+?)</span>' />
<cfset results = reFindAll(pattern, text, 2) />
<cfloop index="i" from="1" to="#ArrayLen(results.pos)#">
    <cfoutput>match #i#: #Mid(text, results.pos[i], results.len[i])#<br></cfoutput>
</cfloop>
Run Code Online (Sandbox Code Playgroud)

编辑:使用subexnum参数更新了reFindAll.将其设置为2将捕获第一个子表达式.默认值1捕获整个匹配.