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

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

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

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

正規表現

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

Q&A

解決済

4回答

3084閲覧

正規表現で括弧以外のアルファベットだけ置換えしたい

gpioblink

総合スコア12

JavaScript

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

正規表現

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

0グッド

2クリップ

投稿2019/01/12 16:14

動画の英語字幕があります。
この英語字幕の一部を伏せ字にしてタイピングゲームを作ろうとしています。

str.replace(/[A-Za-z]/g, '_')で字幕のアルファベット部分を伏せ字にしていたのですが、問題が発生しました。

このキャプションには、「(動作音)」や「[人名]」など会話以外の内容が括弧にくくられて入っています。
この部分は実際に動画で発音していないので、伏せ字にしたくありません。

括弧内以外のアルファベットにヒットする正規表現を教えてください!

入力例

text

1-[TOM] ♪ Taking care to keep my baggage with me ♪ 2-(banging) Huh?

よくない出力

text

1-[___] ♪ ______ ____ __ ____ __ _______ ____ __ ♪ 2-(_______) ___?

期待する出力

text

1-[TOM] ♪ ______ ____ __ ____ __ _______ ____ __ ♪ 2-(banging) ___?

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

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

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

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

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

guest

回答4

0

ベストアンサー

String.prototype.replace

括弧内以外のアルファベットにヒットする正規表現を教えてください!

正規表現は一度、マッチした文字列には二度とマッチしません
括弧全体にマッチさせてから、マッチした文字列をそのまま返す置換処理にしてください。

JavaScript

1'use strict'; 2const string = '-[TOM] ♪ Taking care to keep my baggage with me ♪\n-(banging) Huh?'; 3const result = string.replace(/([^)]*)|[[^]]*]|([a-zA-Z])/g, function callbackfn (match, alphabet) { 4 return alphabet ? '_' : match; 5}); 6 7console.log(result); // "-[TOM] ♪ ______ ____ __ ____ __ _______ ____ __ ♪\n-(banging) ___?"

丸投げ質問

コードをください・デバッグしてください等の丸投げの質問

何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。
問題や質問は実際に調査や作業に取り組み、具体的なところで生まれると考えるためです。
まずは実際に作業に取り組み、つまづいたところで投稿をしてみてください。

この状況で打開策に悩む気持ちは理解できるので、答えを書きましたが、丸投げ質問は推奨されません。

Re: gpioblink さん

投稿2019/01/13 04:57

編集2019/01/13 06:23
think49

総合スコア18164

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

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

gpioblink

2019/01/13 05:51

回答ありがとうございます!replaceでも複数の引数をとって関数が使えるんですね。すいません、丸投げは気をつけます。
think49

2019/01/13 06:29

[] の例外処理に対応しておきました。
guest

0

一気に1つの正規表現でと言うのは無理です。
splitで、括弧内と括弧外によりわけて、括弧外だけreplaceします。

JavaScript

1str = str.split( /([.*?]|(.*?))/ ).map( 2 function(s){ 3 if(s.match( /([.*?]|(.*?))/ )){ 4 return s; 5 }else{ 6 return s.replace(/[A-Za-z]/g,"_"); 7 } 8 } 9 ).join("");

括弧内を表す正規表現:/([.*?]|(.*?))/。この正規表現でsplitする。

splitした配列の各要素について、括弧内ならそのまま、そうでなければreplaceするように、mapで制御する。

最後に配列をjoinして文字列に戻す。

投稿2019/01/13 02:51

otn

総合スコア84557

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

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

gpioblink

2019/01/13 05:29

回答ありがとうございます!先読みとか後読みとか考えて、挫折していました。これならシンプルでわかりやすいです!2重括弧とかにも対応できそうで、ありがたいです。
guest

0

こんにちは。

会話に出現する単語は、以下の条件を満たすものと考えられます。

  • 半角アルファベット1文字以上で構成される文字列で、
  • かつ、その文字列の直前にある文字は、アルファベットおよび(, [ のいずれでもない。
  • かつ、その文字列の直後にある文字は、アルファベットおよび), ] のいずれでもない。

この条件に沿って、会話中の単語を、これを囲む左右の文字を含めた正規表現

/[^a-z([][a-z]+[^a-z)]]/i

でマッチさせ、このマッチ部分に含まれるアルファベットを _ に変換するような関数
maskingWordsInSpeech(text)
を作りました。

javascript

1const maskingWordsInSpeech = (text) => { 2 let x = text; 3 while(true) { 4 const y = x.replace(/[^a-z([][a-z]+[^a-z)]]/i, 5 str => str.replace(/[a-z]/ig, '_') 6 ); 7 if (x == y) break; 8 x = y; 9 } 10 return x; 11};

以上、参考になれば幸いです。

追記

単語の後にくる文字までマッチさせなければ、whileで回したりせずに以下で済みました。

javascript

1const maskingWordsInSpeech = 2 (text) => text.replace(/[^a-z[(][a-z]+/ig, s => s.replace(/[a-z]/ig, '_'));

投稿2019/01/13 01:24

編集2019/01/13 05:41
jun68ykt

総合スコア9058

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

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

gpioblink

2019/01/13 05:14

回答ありがとうございます!考え方まで教えてもらって、役に立ちます!
jun68ykt

2019/01/13 05:47

@gpioblinkさん どういたしまして。 > 役に立ちます! のことでよかったです。追記に書いた text.replace(/[^a-z[(][a-z]+/ig, s => s.replace(/[a-z]/ig, '_')) で問題なければこれがコード量も少なくて一見良さそうですが、(まだgpioblinkさんご自身も気がついてないような)ご質問にないようなパターンの入力があると、会話の中の単語であっても _ で置き換わらないかもしれませんので、他にもあり得る色々な入力を試してみるとよいかもしれませんね。
gpioblink

2019/01/13 06:08

追記ありがとうございます!一行になっちゃって素晴らしいです!入力パターンって、なんだか競プロみたいですね(笑) 早速、「[CROWD cheering]」のように括弧内にスペースがあるデータを見つけたので、 const maskingWordsInSpeech = (text) => text.replace(/[^ a-z[(][ a-z]+/ig, s => s.replace(/[a-z]/ig, '_')); として素人ながらスペースがあっても対応できるようにしてみました!! 他は今の所大丈夫そうです!!本当にありがとうございます!助かりました
jun68ykt

2019/01/13 06:20

@gpioblinkさん > スペースがあっても対応できるようにしてみました!! なるほど!素晴らしいです ????
think49

2019/01/13 06:32

@gpioblink さん 前提条件に気になる部分があるのですが、 console.log(maskingWordsInSpeech('[-TOM-]')); // [-___-] これは期待通りの動作ですか。
gpioblink

2019/01/13 06:54

@think49 さん ありがとうございます!確かに、これも修正する必要がありそうですね! あと、いま気づいたのですが、最初がアルファベットから始まる場合、例えば「What in the world are you? Tell me!」は、「What in the world are you? ____ __!」となってしまったので、修正が必要そうです。。 全ての条件を網羅するのはなかなか大変ですね
think49

2019/01/13 07:01

@gpioblink さん そもそも、括弧内を全て除外すればよいわけで、文字種を限定する意味がないのではありませんか。 私は「括弧内を全て除外すれば良い」の発想で正規表現を書いていました。
gpioblink

2019/01/13 07:36

ホントだ、そっちのほうが考えやすいかもしれませんね! これが効率的なアルゴリズムっていったものなのでしょうか。 今回のプログラムは、「括弧内除外法」で書いてみようと思います!! みなさん様々なアイディアありがとうございます!
gpioblink

2019/01/13 07:49

みなさんの回答がとても参考になって、正直、全ての回答をベストアンサーにしたいです。 様々なコードの特徴まで指摘していただいたthink49さんを選んで、質問を閉じさせてもらいます! 一番始めに回答いただいたsatochaさん、分かりやすい説明をしていただいたjun68yktさん、括弧内除外の方法を始めに教えてくださったotnさんもありがとうございました!!
jun68ykt

2019/01/13 11:16

@gpioblinkさん > 正直、全ての回答をベストアンサーにしたいです。 私の回答を通じて当初のご質問に要件として明示されていないけれども、有り得る入力について考慮するきっかけにして頂けたようで、大変嬉しく思います。
guest

0

正規表現の密林に迷い込むと簡単には抜けられなくなります。
なので、カッコ内の部分だけを記憶しておいて、あとで合体するというのはどうでしょう。

html

1<div id="org"> 2-[TOM] ♪ Taking care to keep my baggage with me ♪<br> 3-(banging) Huh? 4</div> 5<button onclick="change()">change</button> 6<div id="changed"/>

javascript

1function change(){ 2 var str=document.getElementById('org').innerText; 3 var matchedlist=str.match(/[([].*?[)]]/g); 4 str=str.replace(/[([].*?[)]]/g,'*'); 5 str=str.replace(/[A-z]/g,'_'); 6 var strarray=str.split('*'); 7 str=''; 8 for(var i=0,len=strarray.length;i<len;i++){ 9 str+=strarray[i]; 10 if(matchedlist[i]){ 11 str+=matchedlist[i] 12 } 13 } 14 document.getElementById('changed').innerText=str 15}

投稿2019/01/12 19:40

satocha

総合スコア336

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

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

gpioblink

2019/01/13 05:19

回答ありがとうございます!仮の文字で置き換えるのか、、直感的にわかりやすいです!
think49

2019/01/13 05:38

@satocha さん 一時的に他の文字列に置換する場合は、メタキャラクタとなる文字が含まれた場合を考慮する必要があります。 このコードでは、'abc*xyz' や 'abc(*)xyz)' など、*が含まれた文字列で期待通りに動作しません。
think49

2019/01/13 05:45

> str=str.replace(/[A-z]/g,'_'); この正規表現は、"[\]^_`" にマッチしてしまいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問