2016-07-06 7 views
2

正規表現を使用して文字列の一部を抽出するのにJavascriptを使用しています。時々、彼らはそれらのスペースを持つことができ、各タイプの複数が存在することができる - 私は、さまざまな文字で始まる単語を引き出すしようとしています空白を許可して正規表現を次の特殊文字に一致させる

lorem ipsum !bang #hash #hash2 ^caret word @at sym 

は、私のような文字列があります。私の現在の正規表現は/ ([!#^@>\/*-]\w+)/gmある

text: "lorem ipsum" 
!: "bang" 
#: ["hash", "hash2"] 
^: "caret word" 
@: "at sym" 

:だから私は、次のような値のセットにこの文字列を変換したいです。この種の作品はスペースにマッチしません。上のサンプルからは、ではなく、^caretが生成されます。

これを行うには私のコードは次のとおりです。

var result = {}; 

var re =/([!#^@>\/*-]\w+)/gm; 
var m; 

var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/); 
result["text"] = inputString.substring(0, firstSpecialCharIndex); 

while ((m = re.exec(inputString)) !== null) { 
    if (m.index === re.lastIndex) { 
    re.lastIndex++; 
    } 

    var index = m[1].substring(0,1); 
    if(result[index] == null) 
    result[index] = []; 
    result[index].push(m[1].substring(1)); 
} 

誰もが、私は次の特殊文字にそれの後に複数の単語(ただし、スペースの間にスペースを含む次の特殊文字に一致する方法を知っています)?多くのおかげで

答えて

1

私は簡単にするためtext一部を除去しています。あなたが先読み

([!#^@>\/*-])(.*?)(?=\s[!#^@>\/*-]|$) 

Regex Demo

を使用することができ、グループ1は、シンボルが含まれており、グループ2は、テキストが含まれていて、あなたがしたい場合は、結果をトリミングすることができます。

JSデモ

var inputString = "lorem ipsum !bang #hash #hash2 ^caret word @at sym"; 
 

 
var result = {}; 
 

 
var re = /([!#^@>\/*-])(.*?)(?=\s[!#^@>\/*-]|$)/gm; 
 
var m; 
 

 
var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/); 
 
result["text"] = inputString.substring(0, firstSpecialCharIndex); 
 

 
while ((m = re.exec(inputString)) !== null) { 
 
    var index = m[1]; 
 
    if(result[index] == null) { 
 
     result[index] = []; 
 
    } 
 
    result[index].push(m[2].trim()); 
 
} 
 
document.writeln("<pre>" + JSON.stringify(result) + "</pre>");

+1

ありがとうございます、これはうまくいった答えです。複数の単語/数字/特殊文字で完璧に動作します。ありがとう!! – samiles

0

はこれを試してみてください:カッコ内

/ ((?:[!#^@>\/*-]\w+)(?: [^!#^@>\/*-]\w+)*)/gm 

regex101 example

?:のでサブパターンは、任意のキャプチャを行いませんなります。それを取り除き、変更されたものを見てください。

Chromeにこのコードをテスト済み:

var inputString = "lorem ipsum !bang #hash #hash2 ^long caret word @at sym"; 

var result = {}; 

//var re =/([!#^@>\/*-]\w+)/gm; 
var re =/((?:[!#^@>\/*-]\w+)(?: [^!#^@>\/*-]\w+)*)/gm; 
var m; 

var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/); 
result["text"] = inputString.substring(0, firstSpecialCharIndex); 

while ((m = re.exec(inputString)) !== null) { 
    if (m.index === re.lastIndex) { 
     re.lastIndex++; 
    } 

    var index = m[1].substring(0,1); 
    if(result[index] == null) { 
     result[index] = []; 
    } 
    result[index].push(m[1].substring(1)); 
} 
console.log(result); 

それがうまく動作します。

+0

ありがとう、これはほとんど動作しますが、2単語しか一致しません。 char。あなたは、最後のグループが無限の言葉のために本質的に繰り返すことができる方法を知っていますか?ありがとうございました – samiles

+0

@samiles、それは複数の単語にもマッチします。 'https:// regex101.com/r/iW5pY6/3'を試してみてください。' TEST STRING'を試してみてください。 – spirit

+0

私の正規表現の ' [^!#^ @> \/* - ] \ w +)* '、括弧の後に' * '記号があります。それはあなたが必要とするものを正確に意味します。 – spirit

0

代替のためだけの提案が、正規表現は、非捕捉領域と先読み英数字文字と直前(をspecialcharsに分割するために使用された場合)、キャプチャされた特別なcharを維持しながら、論理は次のように書き直すことができます:

var inputString = 'lorem ipsum !bang #hash #hash2 ^caret word @at sym' 
 

 
var rx = /(?:\s)([!#^@>\/*-](?=\w))/; 
 
var arr = inputString.split(rx); 
 
var result = {text: arr[0]}; 
 
for(var i = 1; i < arr.length; i++){ 
 
\t \t var ind = arr[i++], val = arr[i]; 
 
    var coll = (result[ind] = result[ind] || []); 
 
    coll.push(val);  
 
} 
 

 
console.log(JSON.stringify(result));

主な利点は、特殊文字が式で繰り返されないことです。小さな副次的なものは、検索が一度だけ実行されることです(「テキスト」部分は単に結果の最初の要素です)。 また、単語の途中で複数の単語や特殊文字を使用する場合もあります。'lorem ipsum !bang #ha/sh adfa #ha3sh2 ^caret word asdf @at sym'

関連する問題