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

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

ただいまの
回答率

88.64%

正規表現で完全一致で単語を取得できない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,372

syen2501

score 38

TypeScriptで特定の単語を正規表現で取得したいと思いサンプルなどを調べていました。
目的として、テキストを取得し、特定の語を完全一致で取得したいと思いプログラムを
作成しています。

サンプルとして、下記のプログラムは実行できることを確認しました。

     var str = 'the first 3 letters of the alphabet are abc. not abc123';
     var s = "abc";
     var regexp = eval("/\\b(" + s + ")\\b/g;"); //完全一致させるための正規表現
     console.log(str.search(regexp));

しかし、実際にテキストからドキュメントを取得し同じように正規表現で判定させようとすると
「-1」が帰ってきてしまいます。
原因が分からないので、助言をいただければ幸いです。よろしくお願いします。

'use strict';
import * as vscode from 'vscode';
import * as fs from 'fs';

export function activate(context: vscode.ExtensionContext) {
    console.log('Congratulations, your extension "semieditor" is now active!');
    const readJson = JSON.parse(fs.readFileSync('C:\\Users\\\\shin\\src\\parent_dict.json','utf8'));

    context.subscriptions.push(vscode.commands.registerCommand('extension.color', () => {
        vscode.window.showInformationMessage("Color Range Word");
        const strengthTimeWordList = readJson.強時間;

        function decorateWord() {
            const activeEditor = vscode.window.activeTextEditor;
            const text = activeEditor.document.getText(); //ドキュメント取得
            for (let i = 0; i < strengthTimeWordList.length; i++){
                let word = strengthTimeWordList[i].split('=>');
                let rangeWord = word[0]; //jsonファイル内の左辺(矢印の左側の単語)
                let rangeWordreg = eval("/\\b(" + rangeWord + ")\\b/g;");
                console.log(text.search(rangeWordreg));
            }
        }
        decorateWord();
    }));


<parent_dict.json>

{
    "強時間":["現在=>設置している",
            "(現在=>設置している",
            "現在は=>使わず"
          ]
}

<取得したテキスト>
現在はあるものを使わず、別のものを使用している。
・現在設置しているものを使用すること。
(現在設置している機器の仕様) 

<実行結果>
Congratulations, your extension "semieditor" is now active!
-1
-1
-1

※最終目標として、jsonファイル内の矢印の左と右の単語それぞれで
対応させてその単語だけハイライトで表示するようにしたい。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

私が認識できた限りでは、現在.*設置しているのような正規表現でマッチングさせればとりあえずの目標には届くんじゃないかと思えました。

本当にちゃんとやろうとするなら、MecabとかCabochaとかを使った解析が必要になると思います。
https://qiita.com/nezuq/items/f481f07fc0576b38e81d

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/21 20:23

    回答ありがとうございます。
    「現在.*設置している」の正規表現を他の語でも判定させて無事にマッチングさせることが出来ました。

    キャンセル

0

console.log()での出力箇所を増やしてみて、どの部分が意図しない結果になっているのか絞り込んでみると良いと思います。

追記

文字列のセットが検索対象に含まれるかチェックしたいのであれば、正規表現を使うのではなく、データ構造とロジックを見直せば良いと思います。

データはこんな感じ。

{
    "強時間":[
        ["現在","設置している"],
        ["(現在","設置している"],
        ["現在は","使わず"]
    ]
}

あとは例えば「現在」「設置している」が両方とも見つかった場合に何かするといったように修正すればよい気がします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/21 13:19

    回答ありがとうございます。
    実は「現在=>設置している」としている理由は、「現在」と「設置している」をそれぞれペアとして
    別々の色で表示させようと考えています。
    最初はindexOf()で作成し、結果として「(現在=>設置している」と「現在は=>使わず」は
    ハイライトさせることに成功しました。
    しかし、「現在=>設置している」の「現在」をindexOfで検索するときに、最初の行の「現在は」の
    部分にマッチしていまい本来ハイライトしてほしい語がハイライトされないというバグが起こっています。
    従って、正規表現で判定した方が良いと思い解決法が思いつかず質問しました。
    長々と申し訳ありません。

    キャンセル

  • 2018/10/21 13:38

    回答に追記しました。

    キャンセル

  • 2018/10/21 15:17

    回答ありがとうございます。何度も申し訳ございません。
    追記して頂いた回答でjsonファイルを読み込んだ時に、
    判定する条件として、下記のように行っているのですが、
    indexOf()だと単語を含んでいると処理してしまうので、「現在」という単語を判定する際、
    文章に「現在は」の「現在」で反応してしまいます。完全一致で検索する方法はないですか?
    if (text.indexOf(strengthTimeWordList[i][0]) !== -1 && text.indexOf(strengthTimeWordList[i][1], text.indexOf(strengthTimeWordList[i][0])) !== -1)
    ※例) strengthTimeWordList[0] = ["現在"], strengthTimeWordList[1] = ["設置している"]

    キャンセル

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

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る