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

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

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

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

Q&A

解決済

2回答

2296閲覧

空白を無視した置換処理

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

0グッド

0クリップ

投稿2016/07/19 03:55

編集2016/07/19 04:20

javascript で検索文字列を強調しようと思い、置換処理を実施しています。

javascript

1function highlight(text, words) { 2 var i, len = words.length, re; 3 for (i = 0; i < len; i++) { 4 re = new RegExp(words[i], 'g'); 5 if (re.test(text)) { 6 text = (text).replace(re, '<strong>$&</strong>'); 7 } 8 } 9 return text; 10}

めちゃくちゃ便利なJavaScript オリジナル関数10選を参考に上記で実装していましたが、検索対象の空白を無視して置換したかったため、以下の様に変更しました。

javascript

1function highlight(text, words) { 2 var i, len = words.length, re; 3 for (i = 0; i < len; i++) { 4 re = new RegExp(words[i], 'g'); 5 if (re.test(text.replace(/\s+/g, ""))) { 6 text = (text.replace(/\s+/g, "")).replace(re, '<strong>$&</strong>'); 7 } 8 } 9 return text; 10}

当然ですが、全空白を削除してしまうため、意図した動作にはなりません。
常套手段がありそうな置換ですが、ちょっと探せませんでした。

うまいやり方があれば、ご教示いただけないでしょうか?
よろしくお願いいたします。

実現したい置換イメージ:
元文書1
ほげ ほげ ほげ 検索文字列 ほげ ほげ ほげ

元文書2
ほげ ほげ ほげ 検索 文字 列 ほげ ほげ ほげ

変換後→
ほげ ほげ ほげ <strong>検索文字列</strong> ほげ ほげ ほげ

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

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

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

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

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

Zuishin

2016/07/19 04:16

変換後の例を見ると、空白全削除で良いように見えますが、意図しない変換というのはどういうものでしょうか?
退会済みユーザー

退会済みユーザー

2016/07/19 04:18

サンプルがわかりにくかったですかね。修正します。 要は、検索文字列以外の箇所の空白も削除してしまうということです。
think49

2016/07/19 04:25 編集

To: Zuishinさん、例えば、"foo -> piyo" の置換処理をする場合、"hoge f o o hoge" -> "hoge piyo hoge" のように置換することを期待しているものと想像します。"f o o" の語間の空白は無視しますが、hoge 間の空白はそのまま残します。
guest

回答2

0

ベストアンサー

String#split

ごく素直に実装するなら、

JavaScript

1re = new RegExp(words[i].split('').join('\\s*'), 'g');

正規表現メタキャラクタのエスケープ

しかし、正規表現のメタキャラクタを許す設計なのは意図的なのでしょうか。
個人的には Array#map でエスケープした方がいい気がします。

更新履歴

  • 2016/07/19 13:26 正規表現元の文字列修正('\s+' -> '\s*')
  • 2016/07/19 15:11 正規表現元の文字列修正('\s*' -> '\\s*')

Re: te2ji さん

投稿2016/07/19 04:21

編集2016/07/19 06:12
think49

総合スコア18162

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

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

moriyama

2016/07/19 04:34

横から失礼します。joinメソッドでエスケープされた文字列が一度展開されてしまうので、正しくは「re = new RegExp(words[i].split('').join('\\s*'), 'g');」かと思います。
退会済みユーザー

退会済みユーザー

2016/07/19 04:49

動作は理解できていませんが、お二方の回答で実装したい機能は満足できました。 動作理解後ですが、エスケープも考慮するように変更します。 取り急ぎお礼まで。ありがとうございました。
退会済みユーザー

退会済みユーザー

2016/07/19 04:53

理解できました。ありがとうございました。
think49

2016/07/19 06:13

To: moriyama さん ご指摘ありがとうございます。仰る通りでしたので親記事を修正しました。
guest

0

まず元の文書の空白を取り除きます。

そして検索し、置換対象をリストに入れます。この場合だと、「検索文字列」一つのみリストに入ることになりますが、実際には複数になるでしょう。

これを加工します。まず正規表現のエスケープを行い、次に文字と文字のあいだに \s* を入れます。
「検索文字列」の場合は「検\s索\s文\s字\s列」となります。「注意」の場合は「*\s注\s意\s**」となります。

これを使って置換します。

投稿2016/07/19 04:36

Zuishin

総合スコア28660

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

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

Zuishin

2016/07/19 04:38

これは、検索する文字列が正規表現であると仮定しての実装です。単なる文字列ならば、前半部分は不要です。
退会済みユーザー

退会済みユーザー

2016/07/19 04:52

think49 さんと同じイメージですかね? ありがとうございました。
Zuishin

2016/07/19 04:55

検索文字列がたとえば「検.[abc]字列」のような正規表現だと思っていました。 単なる文字列なら前半部分は不要で think49 さんと同じになります。
退会済みユーザー

退会済みユーザー

2016/07/19 05:07

理解できました。ありがとう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問