Web サイトから複数のイベントを取得しようとしています。イベントの形式は通常通り
... EVENT TITLE & LINK ... START DATE ... END DATE ... <span class="location">LOCATION</span> ...
「...」は、スタイル情報と改行を含むいくつかの html タグです。これらのイベント文字列から LINK、START DATE、END DATE、および LOCATION を抽出したいと考えています。周囲の html コード「...」の形式は完全に規則的であるため、4 つの情報を取得するのは簡単です。周囲のタグを照合して、必要な部分を抽出します。たとえば、次のようになります。
'|...<abbr class="dtstart">(.{10}).*?</abbr>...|s'
「(.{10})」は開始日です。
問題は LOCATION です。いくつかのイベントは場所とともにリストされ、他のイベントはリストされていないため、一部のイベントではスパン タグ <span class="location">LOCATION</span> が存在し、他のイベントでは単純に欠落しています。 .
だから私の質問は:
LOCATION を一致させるにはどうすればよいですか?
私が試したら
preg_match_all('|...<span class="location">(.+?)</span>...|s', $contents, $matches, PREG_SET_ORDER);
場所のないイベントでは、そのイベントと一致しません (ただし、場所があるイベントの場所を取得します)。一方、試してみると
preg_match_all('|...(?:<span class="location">(.+?)</span>)...|s', $contents, $matches, PREG_SET_ORDER);
どのイベントでも、そのコードはすべてのイベントに一致しますが、LOCATION は (存在する場合でも) $matches の一部ではありません。
では、規則的だがオプションの部分文字列の不規則な部分を一致させるにはどうすればよいでしょうか?
ありがとうございました!
編集(zigdonによる質問への回答として):
問題は、LOCATION を他のイベント データと一致させる必要があることです。結果として、「Congress of Society of Regex (Web サイトへのリンク)、4 月 7 日から 4 月 10 日、ベルリン」と「オンライン チュートリアル (Web サイトへのリンク、5 月 9 日)」という結果になると想像してください。2 番目のイベントには場所がありません。 , しかし、最初のイベントの場所は、タイトル、リンク、および日付と一致する必要があります. イベントを取得したいページへのリンクは次のとおりです. ソースコードを見て問題を理解することができます: https ://www.fs-psycho.uni-tuebingen.de/events/previous -- 現時点では、
preg_match_all('|<dt class="vevent">\s*?<span class="summary">\s*?(<a href=".+?</a>)\s*?</span>\s*?<span class="documentByLine">\s*?<span>(?:von )?<abbr class="dtstart" title=".{0,30}">(.{10}).{0,6}</abbr>.{5,100}<abbr class="dtend" title=".+?">(.{0,10}).{5,6}</abbr></span>\s*?(?:<span>— <span class="location">(.*?)</span>,</span>)?\s*?</span>\s*?</dt>|', $contents, $matches, PREG_SET_ORDER);
これは機能しますが、回答で述べたように、「ワイルドコード」(自分のものではないサイトから) を使用すると、タグ間で何かが発生する可能性があるため、不満です。イベント部分のすぐ周囲のみに一致し、その間にあるものはすべて非常に開いたままにするソリューション、つまり「.*?|s」を好むでしょう。