0

私のプロジェクトの 1 つで、アプリケーションは、特定の URL へのリンクが特定のページに存在することを確認する必要があります。今日、ユーザーがエラーを報告しました。これは、アプリケーションが検出しなかったリンクです。

  <a\nhref="http://hello.com"...

なぜ機能しないのかをテストしようとしましたが、ここで奇妙な動作が発生しました。この正規表現は次のリンクと一致します。

/\<a.*\nhref=\"http:\/\/hello.com/

しかし、これはしません:

/\<a.*href=\"http:\/\/hello.com/

Rubular は最後の正規表現と一致するため、使用している Ruby バージョン (1.9.3) と何らかの関係があると思います。

4

2 に答える 2

4

なぜ壊れているのか

Rubyでは(ほとんどの正規表現の実装と同様に)、「マルチライン」モードをオンにしない限り、改行以外の.すべての文字に一致します。

irb(main):003:0> "foo\nbar"[/.+/]
#=> "foo"

irb(main):004:0> "foo\nbar"[/.+/m]
#=> "foo\nbar"

公式のRuby1.9正規表現ドキュメントには次のように記載されています。

次のメタ文字も文字クラスのように動作
/./します。-改行を除くすべての文字。
/./m-任意の文字(m修飾子は複数行モードを有効にします)

コードが明示的にすべてを消費した場合は\nすべてうまく機能しましたが、コードをに切り替えた場合は、と.*一致し\nなかったため、一致し続けることができませんでしたhref

それをより良く修正する

正規表現を使用してHTMLを〜解析して消費する代わりに、実際のHTMLパーサーを使用することをお勧めします。

require 'nokogiri' # gem install nokogiri
doc = Nokogiri.HTML( my_html_string )

# Find it using XPath...
first_hello_link = doc.at('//a[starts-with(@href,"http://hello.com")]')

# ...or using CSS
first_hello_link = doc.at('a[href^="http://hello.com"]')

これにより、コードは次の方法でHTMLを堅牢に処理できます。

  • 等号の前後のスペース
  • hrefの前に表示される追加の属性
  • "またはのいずれかで引用'
  • 混合キャピタライゼーション
  • リンクのように見えるがそうではないもの(コメントやスクリプトブロックなど)
于 2012-05-07T15:41:40.427 に答える
1

Ruby の正規表現は、デフォルトでは改行文字と一致しません。m修飾子を追加する必要があります。

/pat/m - Treat a newline as a character matched by .

オプションセクションを見てください:

http://www.ruby-doc.org/core-1.9.3/Regexp.html

于 2012-05-07T15:43:24.793 に答える