こんにちは
この回答では、 <a>を除去 および、<a>で囲む という2つのボタンを置いて、
- <a>を除去 ボタンがクリックされると、 span が a で囲まれていれば、その a を除去する。
- <a>で囲む ボタンがクリックされると、 span が a で囲まれていなければ、それを a で囲む。
という処理を行うコードを回答します。
対象となるHTMLは以下です。ご質問に挙げられているHTMLに、ボタンを2つ追加しています。
html
1<table id="preview">
2 <tr>
3 <td style="text-align: left" class="_con">
4 <div class="nested">
5 <span>インダス文明誕生インダス文明誕生インダス文明誕生</span>
6 <a href="https://ja.wikipedia.org/wiki/"><span>インダス文明誕生インダス文明誕生</span></a>
7 <span>インダス文明誕生</span>
8 </div>
9 </td>
10 </tr>
11</table>
12
13<button id="unwrap_btn"><a>を除去</button>
14
15<button id="wrap_btn"><a>で囲む</button>
以下は、上記を実現するために正規表現を使ってみたコード例です。
javascript
1$(function() {
2
3 // span が a で囲まれていれば、その a を除去する。
4 $('#unwrap_btn').click(function() {
5 const htmlAfter =
6 $('div.nested')
7 .html()
8 .split('\n')
9 .map(line => /<a\s+[^>]+>(.+)</a>/.exec(line) ? RegExp.$1 : line)
10 .join('\n');
11 $('div.nested').html(htmlAfter);
12 });
13
14 // span が a で囲まれていなければ、それを a で囲む。
15 $('#wrap_btn').click(function() {
16 const htmlAfter =
17 $('div.nested')
18 .html()
19 .split('\n')
20 .map(line =>
21 /^\s*(<span>[^<]+</span>)/.exec(line) ?
22 `<a href="https://ja.wikipedia.org/wiki/">${RegExp.$1}</a>` : line)
23 .join('\n');
24 $('div.nested').html(htmlAfter);
25 });
26
27});
28
ちなみにJQuery の .wrap() , .unwrap() を使うとより短いコードで実現できます。
javascript
1$(function() {
2
3 // span が a で囲まれていれば、その a を除去する。
4 $('#unwrap_btn').click(function() {
5 $('a > span').unwrap();
6 });
7
8 // span が a で囲まれていなければ、それを a で囲む。
9 $('#wrap_btn').click(function() {
10 $('div.nested > span').wrap('<a href="https://ja.wikipedia.org/wiki/"></a>');
11 });
12
13});
追記
ご質問にあった、
strをstr2に変えたいのです。
に回答しますと、 HTMLの文字列 str
が与えられたときに、 str
の中に、hrefなどの属性を1つ以上持つような a
タグが含まれる場合、その a
タグで囲まれた内容を返し、そのような a
タグがない場合は何もせず str
をそのまま返す関数は、以下のように書けます。
javascript
1const unwrapOuterLink = str => /<a\s+[^>]+>(.+)</a>/.exec(str) ? RegExp.$1 : str;
先に書いた回答でも、上記の三項演算子を使って、なるべくコードを短くなるようにしています。
または、 RegExp.$1 は非推奨 になっているので、使用を避けるとすれば以下です。
javascript
1const unwrapOuterLink = str => {
2 const m = /<a\s+[^>]+>(.+)</a>/.exec(str);
3 return m ? m[1] : str;
4}
なお、上記の正規表現だと、 a
タグの開始が、 属性のない <a>
である場合には対応できません。また、 str の中に、該当する a
タグが複数あっても、a
を除去するのは先頭のものだけです。これらに対応するには、正規表現を見直さなければなりませんが、まずはご質問に明示的に記載された最低限の要件を満たすものを回答しました。
以上、参考になれば幸いです。