質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

6940閲覧

多重カッコで囲まれた文字列を正規表現でキャプチャする方法

nekonyangon

総合スコア14

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/01/20 15:41

編集2019/01/21 06:20

#前提・実現したいこと
文章中に存在するカッコ(全角)の中身を自動検知してハイライトする機能をJavaScriptと正規表現を用いて実装したいと考えています。

普通にカッコ部分をハイライトするだけであれば単純なのですが、下記のように、カッコが多重(最大4重を想定)になっている文章にも対応し、カッコのレベル毎に異なる色でハイライトしたいと考えています。

例えば、次のような感じです。

  • カッコなし部分(あいうえお) →ハイライトなし
  • 第1カッコ部分(かきくけこ) →黄色
  • 第2カッコ部分(さしすせそ) →黄緑色
  • 第3カッコ部分(たちつてと) →青色
  • 第4カッコ部分(なにぬねの) →ピンク色

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <link rel="stylesheet" href="css/reset.css"> 9 <link rel="stylesheet" href="css/style.css"> 10</head> 11<body> 12 <p class="controlpanel"> 13 <input type="button" value="ハイライトON/OFF" id="btn-onoff"> 14 </p> 15 <div id="content"> 16 <!-- 以下が検索対象の文章(例)です。 --> 17 ① あいうえおあいうえお。<br> 18 ② あいうえお(かきくけこかきくけこ。)あいうえお。<br> 19 ③ あいうえお(かきくけこ(さしすせそさしすせそ。)かきくけこ。)あいうえお。<br> 20 ④ あいうえお(かきくけこ(さしすせそ(たちつてとたちつてと。)さしすせそ。)かきくけこ。)あいうえお。<br> 21 ⑤ あいうえお(かきくけこ(さしすせそ(たちつてと(なにぬねの。)たちつてと。)さしすせそ。)かきくけこ。)あいうえお。<br> 22 </div> 23 <script src="js/jquery-3.3.1.min.js"></script> 24 <script src="js/script.js"></script> 25</body> 26</html>

js

1var backupOriginal = ""; 2 3// 文字列を検索してハイライト用要素を加える 4function replacer( str, word , att ) { 5 var SearchString = '(' + word + ')'; 6 var RegularExp = new RegExp( SearchString, "g" ); 7 var ReplaceString = '<span class="' + att + '">$1</span>'; 8 var ResString = str.replace( RegularExp , ReplaceString ); 9 return ResString; 10} 11 12// ハイライトを加える 13window.onload = function(){ 14 function addhighlight() { 15 backupOriginal = document.getElementById("content").innerHTML; 16 var forShow = backupOriginal; 17 // 単数括弧の場合 18 forShow = replacer( forShow, "((.*?))", "mark1" ); // 第1括弧の中身をキャプチャ=黄 19 // 二重括弧の場合 20 forShow = replacer( forShow, "(([^)]*(.*?)[^(]*))", "mark1" ); // 第1括弧の中身をキャプチャ=黄 21 forShow = replacer( forShow, "([^)]*((.*?))[^(]*)", "mark2" ); // 第2括弧の中身をキャプチャ=黄緑 22 // 三重括弧の場合 23 forShow = replacer( forShow, "(([^)]*([^)]*(.*?)[^(]*)[^(]*))", "mark1" ); // 第1括弧の中身をキャプチャ=黄 24 forShow = replacer( forShow, "([^)]*(([^)]*(.*?)[^(]*))[^(]*)", "mark2" ); // 第2括弧の中身をキャプチャ=黄緑 25 forShow = replacer( forShow, "([^)]*([^)]*((.*?))[^(]*)[^(]*)", "mark6" ); // 第3括弧の中身をキャプチャ=青 26 // 四重括弧の場合 27 forShow = replacer( forShow, "(([^)]*([^)]*([^)]*(.*?)[^(]*)[^(]*)[^(]*))", "mark1" ); // 第1括弧の中身をキャプチャ=黄 28 forShow = replacer( forShow, "([^)]*(([^)]*([^)]*(.*?)[^(]*)[^(]*))[^(]*)", "mark2" ); // 第2括弧の中身をキャプチャ=黄緑 29 forShow = replacer( forShow, "([^)]*([^)]*(([^)]*(.*?)[^(]*))[^(]*)[^(]*)", "mark6" ); // 第3括弧の中身をキャプチャ=青 30 forShow = replacer( forShow, "([^)]*([^)]*([^)]*((.*?))[^(]*)[^(]*)[^(]*)", "mark3" ); // 第4括弧の中身をキャプチャ=ピンク 31 32 document.getElementById("content").innerHTML = forShow; 33 } 34 35 // ハイライトを消す 36 function clearhighlight() { 37 document.getElementById("content").innerHTML = backupOriginal; 38 backupOriginal = ""; 39 } 40 // ハイライトを加えるか消すかを判断 41 function highlightcheck() { 42 if( backupOriginal.length == 0 ) { 43 addhighlight(); 44 } else { 45 clearhighlight(); 46 } 47 } 48 49 document.getElementById("btn-onoff").onclick = highlightcheck; 50}; 51

#発生している問題

実行すると以下のようになり、③以下が上手くハイライトできていません。

イメージ説明

以下のような処理結果(wordで作成)になるようにしたいのですが、どのようにコーディングしたらよいでしょうか。
イメージ説明

Rubular(https://rubular.com/)で上記JavaScript中の正規表現を試したところ、マッチ・キャプチャともに上手くいきましたので、正規表現自体は合っているように思われるのですが。。

正規表現にお詳しい方、どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

こういうのはだめでしょうか?
とりあえず動作確認用にjQueryバージョン

javascript

1<style> 2#content span{display:inline-block;background-Color:yellow;} 3#content span span{background-Color:lime;} 4#content span span span{background-Color:aqua;} 5#content span span span span{background-Color:fuchsia;} 6</style> 7<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 8<script> 9$(function(){ 10 $('#btn-onoff').on('change',function(){ 11 var txt=$('#content').html(); 12 if($(this).prop('checked')){ 13 txt=txt.replace(//g,"<span>(").replace(//g,")</span>"); 14 }else{ 15 txt=txt.replace(/<span>(/g,"(").replace(/</span>/g,")"); 16 } 17 $('#content').html(txt); 18 }); 19}); 20</script> 21<label><input type="checkbox" id="btn-onoff">ハイライトON/OFF</label> 22<div id="content"> 23① あいうえおあいうえお。<br> 24② あいうえお(かきくけこかきくけこ。)あいうえお。<br> 25③ あいうえお(かきくけこ(さしすせそさしすせそ。)かきくけこ。)あいうえお。<br> 26④ あいうえお(かきくけこ(さしすせそ(たちつてとたちつてと。)さしすせそ。)かきくけこ。)あいうえお。<br> 27⑤ あいうえお(かきくけこ(さしすせそ(たちつてと(なにぬねの。)たちつてと。)さしすせそ。)かきくけこ。)あいうえお。<br> 28</div> 29

投稿2019/01/21 07:12

yambejp

総合スコア114814

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nekonyangon

2019/01/21 10:29

とてもご丁寧に回答いただきありがとうございます! こういう方法もあるのですね!試してみましたが、確かにこれでもワークしそうです。 様々なパターンへの対応を考えると正規表現の方がよいのかなと考えていたのですが、正規表現ではやはり難しそうでしょうか。。
yambejp

2019/01/21 10:34

つねに一つしか要素をもたないわけじゃないので大変な割に 効果が薄いので正規表現で調整する案件じゃないと思います (aaa(bbb(ccc)ddd)eee(fff)ggg(hh(iii))jjj) 的な状況になったときにめんどくさい
nekonyangon

2019/01/24 13:03

ありがとうございます。 いろいろやってみた結果、正規表現だと難しいということを理解いたしました。 yamabejp様とKojiDoi様にご教示いただいた方法を組み合わせて何とか実装を試みたいと思います!
guest

0

ベストアンサー

入れ子構造のデータの処理に正規表現はなかなか難しいと思います。
私が思いつくのは、データをカッコで分割し、左から右にそれぞれの要素の階層の深さをチェックしつつ<span>タグを埋め込んでいくという手法です。

var a="abc(def(ghi)jkl(mno)((pqr))stu)"; var x=a.split(/([()])/); console.log(x); nest=0; out=""; for(var i=0; i<x.length; i++){ if(x[i]=="("){ nest++; out += '(<span class="nest'+nest+'">'; }else if(x[i]==")"){ out += '</span>)'; nest--; }else{ out += x[i]; } } console.log(a); console.log(out);

javascriptにはあまり慣れていないので、断片的かつあまりカッコよくないコードですみませんが。

投稿2019/01/22 19:13

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nekonyangon

2019/01/24 13:01

ありがとうございます。 入れ子構造だとやはり難しいのですね。。ご教示いただいた方法で何とかなりそうなので、その方向で実装してみたいと思います!
guest

0

投稿2019/01/20 15:46

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問