69569


下記の解釈で合っているのか見て欲しいです。

[code]

    <a[\s\S]*?class="product-card__image-link"[\s\S]*?data-index=".*?"[\s\S]*?href="(.*?)"
    
[/code]

  * おそらく`[\s\S]`はスペースの事を指していると思われる。
  * `*?`はメタ文字で直前にスペースが一個以上あっても検索する対象となる。
  * classの中身が追加されて、先ほどと同様にスペースが入ってdata-index属性に入る文字列が検索対象となる。
  * 同様にスペースでhref属性に入る文字列が何でも検索対象となる。


CC BY-SA 4.0
2020-08-15T03:41:56.497
69567
2020-08-15T16:47:59.040
2020-08-15T16:35:57.520
3060
22565
question
正規表現
正規表現の [\s\S]、.*? について


ざっくり「`product-card__image-link`クラスと、`data-
index`と`href`属性を持った`a`タグ」を検索する正規表現を意図したのでしょうが、そうでない文字列も検索対象になってしまいます。以下理由を示します。

> おそらく`[\s\S]`はスペースの事を指していると思われる。  
>  ...  
>  classの中身が追加されて、先ほどと同様にスペースが入ってdata-
> index属性に入る文字列が検索対象となる。同様にスペースでhref属性に入る文字列が何でも検索対象となる。

`\s`は空白文字（スペース、タブ、改行）にマッチします。`\S`は空白文字 **以外**
すべての文字にマッチします。したがって、その両方を組み合わせた`[\s\S]`は、すべての文字にマッチするということになります。大文字小文字が紛らわしいですね。

`.`と違って、改行文字にもマッチします。

> `*?`はメタ文字で直前にスペースが一個以上あっても検索する対象となる。

`*?`単体では何にマッチするかはわかりません。たとえば`[\s\S]*?`では、

  * `[\s\S]` すべての文字が
  * `*` 0個以上並んだ文字列にマッチする
  * `?` ただし、なるべく範囲が狭くなるように

という意味になります。

まとめると、この正規表現は以下のような文字列にマッチしてしまいます。

[code]

    <!-- 思惑通り -->
    <a class="product-card__image-link" data-index="abcd" href="/path/to/dir"
    
    <!-- aの後はスペースでなくてもよい -->
    <astronaut class="product-card__image-link"data-index="abcd" href="/path/to/dir"
    
    <a  hogehoge class="product-card__image-link"  hogehoge data-index="" hogehoge   href="/path/to/dir"
    
    <!-- 改行があってもよい -->
    <a  
    class="product-card__image-link" 
    data-index="abcd" 
    href="/path/to/dir"
    
[/code]

正規表現は面倒でややこしいものですので、有志が正規表現をビジュアライズするサイトや、実験できるサイトを作っています。例として[Regexper](https://regexper.com/#%3Ca%5B%5Cs%5CS%5D*%3Fclass%3D%22product-
card__image-link%22%5B%5Cs%5CS%5D*%3Fdata-
index%3D%22.*%3F%22%5B%5Cs%5CS%5D*%3Fhref%3D%22%28.*%3F%29%22)と[RegExr](https://regexr.com/5a8as)に質問の正規表現を打ち込んでみました。ここでいろいろ試してみるとよいと思います。


CC BY-SA 4.0
2020-08-15T04:43:42.813
69569
2020-08-15T04:43:42.813
7500
69567
answer


`[\s\S]` と `.*?` のパターンについては [sei0o
さんの回答](https://ja.stackoverflow.com/a/69569)
で詳しく説明されていますので、その他の気になった点を補足してみます。

`.*?` の部分は `(.*?)` のように丸括弧 `()` で括られていますが、これは括弧内でパターマッチした文字列を **後方参照**
で取り出すためだと思います。

今回の場合なら恐らく `href=` で指定されるURL部分を取り出すのが目的で、パターンの全体を見ると

  * アンカータグ `<a>` で、かつ
  * `class="product-card__image-link"` と `data-index=` を含むもの
  * ただしその他の属性も含まれる可能性があるので、曖昧な箇所には `[\s\S]` や `.*?` を当てている

と考えられます。


CC BY-SA 4.0
2020-08-15T16:47:59.040
69589
2020-08-15T16:47:59.040
3060
69567
answer