2011-10-18 4 views
1

まずは:私は正規表現を使ってHTMLを解析すべきではないことを知っています。私はそれを何百回も読んだことがある。しかし、私が仕事をしなければならないツールは正規表現ベースのツールなので、HTMLパーサーなどは使用できません。とにかく、私はあなたにすべての懸念をありがとう、しかし、私は正規表現との仕事をする必要がある場合、素晴らしい。そうでない場合は、この機能を無効にする必要があります。Regex PHP - 内部の部分文字列を見つける<div></div>タグ

質問です:

短い説明:私は(重要なもののためのWordpressの、)PHPで生成されたWebページにタグ内に含まれる部分文字列を返すために正規表現式を必要とします。

詳しい説明:私のページの中にあるさまざまな<div class="post-bodycopy clearfix">の中にあるゲームの名前(この例では、ゲームの名前Batman: Arkham City)を見つける必要があります。これは、ポストのタイトル、サイドバー、どこにでも、ポストボディの内部にあるゲームの名前だけを必要とすることを意味します。次に、この名前をpreg replaceなどを使用したリンクに置き換えます。

ウェブで同様の質問を検索しましたが、そのような「タグ内にあるすべてを教えてください」という質問のみが見つかりました。ここで

は私の生成されたコードの中から代表的なポストである:

<div class="post-268445 post hentry category-world-community-gamer tag-games tag-geral tag-lancamentos tag-noticias tag-pc tag-ps3 tag-xb360" id="post-268445"> 
<div class="post-kicker"><?php get_cat_icon(); ?><a href="http://www.gameblogs.com.br/category/world-community-gamer/" title="World Community Gamer" onclick="return TrackClick('http://www.gameblogs.com.br/category/world-community-gamer/','')"><img src="http://www.gameblogs.com.br/wp-content/uploads/world-community-gamer.png" width="48" height="48" alt="" title="World Community Gamer" /></a></div> 
<div class="post-headline">  <h2> <a href="http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html?utm_source=gameblogs&utm_campaign=data-para-batman-arkham-city-no-pc" rel="bookmark" title="Permanent Link to Data para Batman: Arkham City no PC" target="_blank" onclick="return TrackClick('http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html?utm_source=gameblogs&utm_campaign=data-para-batman-arkham-city-no-pc','')">Data para Batman: Arkham City no PC</a></h2> </div> 
<div class="post-byline"><img src="http://www.gameblogs.com.br/wp-content/themes/atahualpa353/images/icons/user.gif" alt="" /> <a href="http://www.gameblogs.com.br/author/_otaviofqueiroz/" title="Posts de @_otaviofqueiroz" onclick="return TrackClick('http://www.gameblogs.com.br/author/_otaviofqueiroz/','')">@_otaviofqueiroz</a>, do <img src="http://www.gameblogs.com.br/wp-content/themes/atahualpa353/images/icons/home.gif" alt="" /> <a href="http://www.worldcommunitygamer.com/" target="_blank" target="_blank" onclick="return TrackClick('http://www.worldcommunitygamer.com/','')">WCG | World Community Gamer: Jogos, Análises e Tecnologia</a>, <img src="http://www.gameblogs.com.br/wp-content/themes/atahualpa353/images/icons/calendar_month.png" alt="" /> 18/10/11 | Compartilhe: <a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html?utm_source=gameblogs&utm_campaign=data-para-batman-arkham-city-no-pc" data-text="WCG | World Community Gamer: Jogos, Análises e Tecnologia: Data para Batman: Arkham City no PC" data-count="horizontal" data-via="GameBlogsBR" data-lang="fr" target="_blank" onclick="return TrackClick('http://twitter.com/share','')">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="post-bodycopy clearfix"><p> <a href="http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank" onclick="return TrackClick('http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html','')"><img src="/wp-content/plugins/wordpress-image-resizer/thumb/phpThumb.php?fltr=usm&#038;src=http://2.bp.blogspot.com/-9oKlgIND3qY/Tp3Aimju2nI/AAAAAAAABxA/Q585nqpdsRI/s1600/batman_arkham_city_screens16-620x348.jpg&#038;w=200" align='left'></a> 
<p>A Warner divulgou a data de lançamento para Batman: Arkham City no PC. O jogo que terá a sua versão para os consoles (PS3 e Xbox 360) lançada nessa sexta-feira, chegará as lojas na versão PC no dia 18 de Novembro. Apesar da demora [...]<br /><a href=http://www.worldcommunitygamer.com/2011/10/data-para-batman-arkham-city-no-pc.html?utm_source=gameblogs&#038;utm_campaign=data-para-batman-arkham-city-no-pc>[continua no site original...]</a></p></div> 
<div class="post-footer"><img src="http://www.gameblogs.com.br/wp-content/themes/atahualpa353/images/icons/tag.gif" alt="" /> <a href="http://www.gameblogs.com.br/tag/games/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/games/','')">Games</a>, <a href="http://www.gameblogs.com.br/tag/geral/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/geral/','')">Geral</a>, <a href="http://www.gameblogs.com.br/tag/lancamentos/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/lancamentos/','')">lançamentos</a>, <a href="http://www.gameblogs.com.br/tag/noticias/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/noticias/','')">Notícias</a>, <a href="http://www.gameblogs.com.br/tag/pc/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/pc/','')">PC</a>, <a href="http://www.gameblogs.com.br/tag/ps3/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/ps3/','')">PS3</a>, <a href="http://www.gameblogs.com.br/tag/xb360/" rel="tag" onclick="return TrackClick('http://www.gameblogs.com.br/tag/xb360/','')">XB360</a><br>Todos os posts do <a href="http://www.gameblogs.com.br/category/world-community-gamer/" onclick="return TrackClick('http://www.gameblogs.com.br/category/world-community-gamer/','')">World Community Gamer</a></div></div><!--/Post --> 

私はすでに発見のために次のことを試してみた:

意味
$<div class\=\"post-bodycopy clearfix\">(.+?)(Batman: Arkham City)(.+?)(?=<div class\=\"post-footer\">)$s 

:続く、DIVの開始タグを見つけますバットマン:Arkham Cityの後に何かが続いて、マルチフリンジを考慮して、ポストフッターの開始タグdivまで。

と交換するために、以下:

<div class="post-bodycopy clearfix">/1<a href="http://www.mylink">Batman: Arkham City</a>/3 

正規表現は私のライブのウェブサイトに期待されるすべての部品を返す、http://regexlib.comで動作しますが、ではないいくつかの理由。それは若干の軽微な問題でなければならない。

しかし、これらの部分文字列を見つけるためには、私のsolutonが最もエレガントな(そしてサーバを消費する/より安価な)方法ではないと確信しています。

これを達成するためのより洗練された方法がありますか?お願いします?

ありがとうございます!

+0

なぜパーサを*使用できないのですか?正規表現よりもHTMLパーサーを使用するようにコードをハックする方が簡単だと思います。 – Blender

+0

あなたはhtmlページで "バットマン:アルカムシティ"を見つける方法を尋ねているのですか、htmlページで地球上のすべてのゲームを見つける方法を尋ねていますか? – bozdoz

+0

@bozdozページあたりの特別ゲームです。ありがとう。 – Daniel

答えて

0

$ title = 'バットマン:アルカムシティ';

検索:{(?<=<div class="post-bodycopy clearfix">)(.+?)($title)(.+?)(?=<div class="post-footer">)}s

置き換える:
\1<a href="http://www.mylink">\2</a>\3
または
$1<a href="http://www.mylink">$2</a>$3

編集
をあなたは以下を試すことができます。ちょうどテストするために、HTML文字列の一番下にアーカム市:私はバットマンを追加

'|(<div class="post-bodycopy clearfix">)(.*?)(Batman: Arkham City)(.*?)(</div>)|e' 

:例のPHPはhttp://ideone.com/JtH4s

$title = 'Batman: Arkham City'; 
$divclass = 'post-bodycopy clearfix'; 

$rxtag = 
'< 
(?: 
    \?php\s+.*?\? 
    | (?: 
     (?: 
      (?:script|style)\s* 
     | (?:script|style)\s+(?:".*?"|\'.*?\'|[^>]*?)+\s* 
     )> .*? </(?:script|style)\s* 
    ) 
    | (?: 
     /?[A-Za-z_:][\w:.-]*\s*/? 
     | [A-Za-z_:][\w:.-]*\s+(?:".*?"|\'.*?\'|[^>]*?)+\s*/? 
     | !(?:DOCTYPE.*?|--.*?--) 
    ) 
) 
> 
'; 

// Or, 
// $rxtag_optional = '<[^<>]+?>'; 
// $rxtag = $rxtag_optional; 



$rxmain = 
"~(?xs: 
    (<div (?=\\s)[^>]* 
      (?<=\\s) class \\s* = \\s* \" \\s* (?i-x:$divclass) \\s* \" 
      [^>]* (?<!/) 
    > 
    (?: 
     (?! </?div | (?-x:$title)) 
     (?> $rxtag | [^<] | <) 
    )*? 
    ) 
    ((?-x:$title)) 
    (
     (?: (?!</?div) (?> $rxtag | [^<] | <))*? 
     </div \\s*> 
    ) 
) 
~"; 

//print "$rxmain\n\n"; 

$count = 0; 

$newhtml = preg_replace($rxmain, 
         "$1<a href=\"http://www.mylink\">$2</a>$3", 
         $html, 
         1, 
         $count); 
+0

私は欠けていたものが最初の部分でしたか?ありがとう。しかし、私はいくつかの同僚とこれについて議論していました。ゲームの名前には、例えば、というタグが含まれていないので、それがはるかに複雑になることがわかりました。出来ますか? – Daniel

+0

さらにいくつかのテストを行った後、何らかの理由で正規表現がdivタグの外にバットマン:Arkham Cityを捕まえてしまいます。 :( – Daniel

+0

私のポストに追加された新しい正規表現を試すことができます。 – sln

0

は、私はPHPで以下の正規表現と一緒に例hereを入れてここにあります。それは働いているようだ。お知らせ下さい。

0

あなたは正規表現を使用して主張し、あなたの<div class="post-bodycopy clearfix">...</div>要素がネストされたdiv要素が含まれることはありません場合は、ここではまともな仕事をする必要があり、二重のコールバックソリューションです:

// Linkify title inside post-bodycopy DIV text. 
function p($text) { 
    global $title, $link; 
    // Set title to be found and linkify URL address. 
    $title = 'Batman: Arkham City'; 
    $link = 'http://www.mylink'; 
    // Match non-nested "post-bodycopy" class DIV element. 
    $re = '%<div class="post-bodycopy clearfix">(.+?)</div>%si'; 
    return preg_replace_callback($re, 'p_cb', $text); 
} 
function p_cb($matches) { 
    // Match tag (in $1) and non-tag stuff (in $2). 
    $re = '% 
      (</?\w+ # Either $1: An open or close tag. 
      (?:\s+[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[^\s<>]+))?)* 
      \s*/?> 
     ) 
     | ([^<]+) # Or $2: Non-tag stuff. 
     %x'; 
    $matches[1] = preg_replace_callback($re, 'p_cb_cb', $matches[1]); 
    return '<div class="post-bodycopy clearfix">'. $matches[1] .'</div>'; 
} 
function p_cb_cb($matches) { 
    global $title, $link; 
    # Return open and close tags unchanged. 
    if (isset($matches[1]) && $matches[1]) return $matches[1]; 
    # Process non-tag text, converting text to link. 
    $matches[2] = str_replace(
     $title, 
     '<a href="'. $link .'">'. $title .'</a>', 
     $matches[2]); 
    return $matches[2]; 
} 

p()機能は、HTMLファイルを処理内容その正規表現は<div class="post-bodycopy clearfix">...</div>要素と一致し、DIVの内容をp_cb()コールバック関数に渡します。この最初のコールバック関数は、オープンタグまたはクローズタグ(キャプチャグループ$1)またはタグ以外のもの(キャプチャグループ$2)に一致する正規表現を使用してDIVの内容を処理/処理します。次にこれは第2のコールバック関数p_cb_cb()を呼び出し、単に開/閉タグ($1)をそのまま返し、次にstr_replace()を使用して$titleテキストのすべてのインスタンスを目的のリンクに変換します。

あなたのHTMLマークアップは無効であることに注意してください。引用符で囲まなければならない多くの引用符で囲まれていないタグ属性値があります。

関連する問題