teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追記

2018/02/21 01:41

投稿

yambejp
yambejp

スコア117906

answer CHANGED
@@ -53,4 +53,30 @@
53
53
  print htmlspecialchars($str);
54
54
  print "</pre>";
55
55
  ```
56
- ※上記(4)はNGです
56
+ ※上記(4)はNGです
57
+
58
+ # 追記
59
+ よくよく考えたら正規表現でaタグをひろったあと
60
+ callbackの中でdom処理をしてもいいかもしれません
61
+ ```PHP
62
+ $str=<<<eof
63
+ (1)test<a href="hoge.htm">hoge1</a>test<br>
64
+ (2)test<a href="hoge.htm" target="fuga">hoge2</a>test<br>
65
+ (3)test<a href="hoge.htm" data-target="fuga">hoge3</a>test<br>
66
+ (4)test<a class="hoge target" href="hoge.htm">hoge4</a>test<br>
67
+ eof;
68
+
69
+ $pattern="/<a\s.*?</a>/";
70
+ $replacement=function($x){
71
+ $doc=new DOMDocument();
72
+ $doc->loadHTML($x[0]);
73
+ $node=$doc->getElementsByTagName("a")[0];
74
+ $target=$node->getAttribute("target");
75
+ if(empty($target)) $node->setAttribute("target","_blank");
76
+ return $doc->saveXML($node);
77
+ };
78
+ $str=preg_replace_callback($pattern,$replacement,$str);
79
+ print "<pre>";
80
+ print htmlspecialchars($str);
81
+ print "</pre>";
82
+ ```

1

参考

2018/02/21 01:41

投稿

yambejp
yambejp

スコア117906

answer CHANGED
@@ -23,4 +23,34 @@
23
23
  本来小文字指定の「_blank」が不適当な大文字化していたり
24
24
  本来のタグ終端子である「>」が途中で文字列として出現したり
25
25
  どこまでフォローすべきかです。
26
- そういうの煩わしさを防ぐのがDOMとしての処理です
26
+ そういうの煩わしさを防ぐのがDOMとしての処理です
27
+
28
+ # sample
29
+ 文字列での検証は例外が多すぎるためかなり困難であることはすでにお伝えしたとおりですが
30
+ 逆に言えば極端に変なタグ設定をしていなければ以下で大丈夫だとおもいます
31
+ - まずはaタグを拾う
32
+ - aタグの中身を検証して書き換える
33
+
34
+ ```PHP
35
+ <?PHP
36
+ $str=<<<eof
37
+ (1)test<a href="hoge.htm">hoge1</a>test<br>
38
+ (2)test<a href="hoge.htm" target="fuga">hoge2</a>test<br>
39
+ (3)test<a href="hoge.htm" data-target="fuga">hoge3</a>test<br>
40
+ (4)test<a class="hoge target" href="hoge.htm">hoge4</a>test<br>
41
+ eof;
42
+
43
+ $pattern1="/(?<=<a\s).*?(?=>)/";
44
+ $replacement=function($x){
45
+ $ret=$x[0];
46
+ if(!preg_match("/(?<=\s)target/i",$x[0],$m)){
47
+ $ret.=' target="_blank"';
48
+ }
49
+ return $ret;
50
+ };
51
+ $str=preg_replace_callback($pattern1,$replacement,$str);
52
+ print "<pre>";
53
+ print htmlspecialchars($str);
54
+ print "</pre>";
55
+ ```
56
+ ※上記(4)はNGです