ColdFusion, REGEX - по заданному тексту найдите все элементы, содержащиеся в SPAN - PullRequest
2 голосов
/ 10 марта 2010

Я хочу узнать, как создать REGEX в Coldfusion, который будет сканировать большой элемент HTML-текста и создавать список элементов.

Элементы, которые я хочу, находятся между следующими

<span class="findme">The Goods</span>

Спасибо за любые советы, чтобы получить это.

Ответы [ 2 ]

6 голосов
/ 10 марта 2010

Вы не говорите, какая версия CF.Начиная с версии 8 вы можете использовать REMatch , чтобы получить массив

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

. Используйте ArrayToList, чтобы превратить его в список.Для более старой версии используйте REFindNoCase и используйте Mid () для извлечения подстрок.

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш следующий комментарий, процесс использования REFind для возврата всех совпадений довольно сложен, поскольку функция возвращает только первое совпадение.Это означает, что вам действительно нужно много раз вызывать REFind, каждый раз передавая новую стартовую позицию.Бен Форта написал 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>

Это дает вам начало (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>

РЕДАКТИРОВАТЬ: обновлен reFindAll с аргументом subexnum.Установка этого значения в 2 захватит первое подвыражение.Значение по умолчанию 1 фиксирует полное совпадение.

2 голосов
/ 10 марта 2010

Попробуйте изучить возможность заставить ваш HTML работать с обычным парсером DOM и запросить его через XPath, вместо того, чтобы использовать это через мерзость на основе регулярных выражений.

  1. , чтобы сделать ввод HTML доступным, проходчерез jTidy (см. http://jtidy.riaforge.org/)
  2. Как только вы получите правильно сформированный XML / XHTML, создайте из него XML-документ
    <cfset dom = XmlParse(scrubbedHtml, true)>
  3. запросите документ XML с использованием XPath
    <cfset result = XmlSearch(dom, "//span[@class='findme']")>

Готово.

РЕДАКТИРОВАТЬ: Coldfusion XmlSearch() не имеет большой поддержки пространства имен XML. Если вы в конечном итоге создаете XHTML вместо более рекомендуемого XML, используйтеследующий XPath (обратите внимание на двоеточие) "//:span[@class='findme']" или "//*:span[@class='findme']". Для получения дополнительной информации см. здесь и здесь .

См. документацию jTidy API для полного обзора того, что может сделать jTidy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...