まず回答から
Using namespace system
Using namespace System.Text
Using namespace System.Text.RegularExpressions
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$params = @{"q"="Powershell"}
$vbCrLf = "`r`n"
$strTest = @"
<div>
<div>
<div>
<a href = "https://www.excite.co.jp">
excite 1
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.google.co.jp">
gooogle 2
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.yahoo.co.jp">
yahoo 3
</a>
<a href = "https://www.yahoo.co.jp">
Sub
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.baidu.com">
baidu 4
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.naver.com">
naver 5
</a>
</div>
</div>
</div>
"@
$ret3 =[regex]::Matches($strTest, "^<div`>",'multiline');$ret3.Count; #"(.*)(.*)(.*)(.*)(\s*<`/a>\s*<`/div>\s*<`/div>\s*<`/div>)",'multiline');$ret3[0].Value ; $ret3.count
# Indexは0から始まるが、0はいらない。
for($i = 1 ; $i -lt $ret3.Count;$i++){
if($i -eq 1){
# 1文字目からしているすると食われるので、0から書く
$str11 = $strTest.Substring(0, $ret3[1].Index)
}ElseIf($i -eq ($ret3.count -1 ) ){
$str11 = $strTest.Substring( $ret3[$i].Index, $strTest.Length - $ret3.Item($i).index)
}Else{
$str11 = $strTest.Substring( $ret3.Item($i -1 ).Index, $ret3.Item($i).index - $ret3.Item($i -1 ).index )
}
write-host $i $str11
}
今回の並びの特徴
<div>が3つ続き</a></div></div></div>
というブロックになっているが、全く同じではない。
<div>
<div>
<div>
<a href = "https://www.excite.co.jp">
excite 1
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.google.co.jp">
gooogle 2
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.yahoo.co.jp">
yahoo 3
</a>
<a href = "https://www.yahoo.co.jp">
Sub
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.baidu.com">
baidu 4
</a>
</div>
</div>
</div>
<div>
<div>
<div>
<a href = "https://www.naver.com">
naver 5
</a>
</div>
</div>
</div>
♯ はまった点
ブロックで抜くことはできない
現在ブロックで抜くことができない
"`<div>*\s*<`\a>\s*<`\div>\s*<`\div>\s*<`\div>`"
\
BingChatの貪欲
このパターンはどうか
"(<div>)(*)(\s*</a>([\s\S])*</div>\s*</div>\s*</div>)"
このパターンは、divタグの中にaタグがあるときに、divタグとaタグを閉じるためのものです。しかし、このパターンにはいくつかの問題があります。
()は、任意の文字を0回以上繰り返すことを意味しますが、これは貪欲な量指定子です。つまり、できるだけ多くの文字にマッチしようとします。そのため、divタグやaタグの属性に他のタグが含まれている場合には、正しくマッチしません。
(\s)は、空白文字を0回以上繰り返すことを意味しますが、これも貪欲な量指定子です。つまり、できるだけ多くの空白文字にマッチしようとします。そのため、divタグやaタグの後に他のタグがある場合には、正しくマッチしません。
([\s\S]*)は、空白文字以外の任意の文字を0回以上繰り返すことを意味しますが、これも貪欲な量指定子です。つまり、できるだけ多くの文字にマッチしようとします。そのため、aタグの中に他のタグがある場合には、正しくマッチしません。
これらの問題を解決するためには、以下のようなパターンを使うことができます。
"(<div[>]*>)(<a[>]>)(.?)</a>(.?)</div>\s</div>\s*</div>"
[^>]は、>以外の任意の文字を意味します。これにより、divタグやaタグの属性に他のタグが含まれていてもマッチします。
?は、直前の量指定子を非貪欲にします。つまり、できるだけ少ない文字にマッチしようとします。これにより、divタグやaタグの後に他のタグがあってもマッチします。
.*?は、任意の文字を0回以上繰り返すことを意味しますが、非貪欲な量指定子です。つまり、できるだけ少ない文字にマッチしようとします。これにより、aタグの中に他のタグがあってもマッチします。
暫定結論
つまりBing Chatもケチをはつけられるが正解は得られない。
原因は長いから。
発想を変える
最初の<div>
のみにマッチさせる。
そして、Indexを使う。
0....$ret[1].length.....$ret[2].length.....$ret[3].length.....$ret[k].length.....$ret[n-1].length.......文字列長
そうするとこのようになる
つまりインデックス1とインデックスn-1、それ以外
の3つに分けて文字列の起点、文字列の長さを設定して、SubStirngで抜く
その他
Indexの書き方
$i -1
のときの配列のIndexの表記は角かっこではダメ
$ret[$i - 1]
これはダメ
$ret.Item($i - 1)
これはOK
Forは0からではない
Indexは0からつくが、forは1から始める。