2016-09-08 14 views
0

regexを使用して入力文字列からキー値文字列を取得しますか?私は正規表現を使用して文字列内のキーと値のペアを見つけようと(それが賢明であるかどうかわからない!)ここに私の文字列でい

key1=key1 value key2=key2 value_key3=something key3=key3_value 

key1key2key3がキーです。 ご覧のとおり、値には空白が含まれている可能性があります。 key2の値が表示されている場合はkey3key2 value_**key3**=something)です!申し訳ありませんが、これは私の入力方法です。

まだ終わっていません。私は以下のような任意の順序でキーを持つことができます。

key1=key1 value 
key2=key2 value_key3=something 
key3=key3_value 

key3=key3_value key1=key1 value key2=key2 value_key3=something 
key2=key2 value_key3=something key1=key1 value key3=key3_value 

は今、私は、後のようなキーと値のペアを構築することができますので、キー、値のために私の右のグループを見つけた正規表現を持つようにしたいです

私は正規表現key1=(.*)key2=(.*)key3=(.*)を試しましたが、これは最初の文字列に対してのみ機能します。 2番目と3番目の文字列のようにキーの順序を変更すると、その文字列は消えてしまいます。

+0

は内に埋め込まれたキーの前に必ずアンダースコアです価値? – Bohemian

+0

@Bohemianアンダースコアは埋め込みキーの前に必ずしも必要ではなく、キーは実際に 'key#'ではなく、 'myproperty'のような実名です。私はちょうどここにそれらを掲示したくない。 – SomeDude

答えて

0

いくつか真剣に考えた後、これは確かに、解ける少しトリッキーです:。。

私が直面した最も重要な問題は、キーの順序だったそうでない場合は、正規表現key1=(.*)key2=(.*)key3=(.*) wou ldで十分でした。

だから私は最初、その後私はその順序を使用して正規表現のランタイムを構築するJavaのindexOf

を使用して、それらを収集することにより、以下のコードキーの順序を得た:

List<String> myPropKeys = new ArrayList<String>(); 
myPropKeys.add("key1"); 
myPropKeys.add("key2"); 
myPropKeys.add("key3"); 

String input1 = "key1=key1 value key2=key2 value_key3=something key3=key3_value"; 
String input2 = "key3=key3_value key1=key1 value key2=key2 value_key3=something"; 
String input3 = "key2=key2 value_key3=something key1=key1 value key3=key3_value"; 

Map<String, String> propMap = getPropValues(input1, myPropKeys); 
propMap = getPropValues(input2, myPropKeys); 
propMap = getPropValues(input3, myPropKeys); 
System.out.println(); 



private static Map<String, String> getPropValues(String input, List<String> myPropKeys) 
{ 
    Map<String, String> propValues = new HashMap<String, String>(); 

    StringTokenizer tokens = new StringTokenizer(input); 
    List<String> propKeyList = new ArrayList<String>(); 
    while(tokens.hasMoreTokens()) 
    { 
     String token = tokens.nextToken(); 
     int equalsIndex = token.indexOf("="); 
     if(equalsIndex != -1) 
     { 
      String propertyToken = token.substring(0, equalsIndex); 
      if (myPropKeys.contains(propertyToken)) 
      { 
       propKeyList.add(propertyToken); 
      } 

     } 
     } 

     StringBuilder sb = new StringBuilder(); 
     for (String propKey : propKeyList) 
     { 
     sb.append(propKey + "="); 
     sb.append("(.*)"); 
     } 

     Pattern p = Pattern.compile(sb.toString()); 
     Matcher m = p.matcher(input); 

     List<String> values = new ArrayList<String>(); 
     if (m.find()) 
     { 
     for (int i = 1; i <= propKeyList.size(); i++) 
     { 
      values.add(m.group(i)); 
     } 

     } 

     if (propKeyList.size() == values.size()) 
     { 
     for (int i = 0; i < propKeyList.size(); i++) 
     { 
      propValues.put(propKeyList.get(i), values.get(i).trim()); 
     } 
     } 

     return propValues; 
} 
0

は別に、各キーの操作を行います。

String key1value = input.replaceAll(".*\\bkey1= *(\\S+).*", "$1"); 
// similar for other keys 

をこれが「=キー1」の後にすべてではないスペースを抽出します。値のkey3の例は、キーが始まる前に単語境界\bが必要であるために処理されます。

+0

これは、最初の文字列に対しても 'k'を与えます。 – SomeDude

+0

私はプラス記号を省いた。編集したバージョン – Bohemian

+0

の値に空白がある場合は、 '\ S'でスペースを明示的に指定していないようです。私には 'key1 value'の代わりに' key1'だけが返されます – SomeDude

0

これはあなたが始めるかもしれません:

(\w+)=((?:(?!\bkey\w+=).)+) 

a demo on regex101.comを参照してください。

私の意見では、key2=key2 value_key3=somethingkey2=key2 value_key3=somethingの区別は最も難しいでしょう。
より良い答えを得るには、実際の入力文字列を入力してください。

+0

ありがとうございます。 key1は 'name'、key2は' person'、key3は 'age'と考えることができます。プロパティは必ずしも 'key'という単語で始まる必要はありません – SomeDude

0

多分これはあなたを助ける:

\b([a-z\d]+)=(.*?)(?=\b[a-z\d]+=|$) 

それは英数字のみかかわらによって構築されたキーに依存します。 のキーにアンダースコアを含めると、の値がであるため、失敗します。 :(そして、キーは大文字を含めることができる場合、フラグが設定されなければならない場合は無視します。それは何

、キー(文字と数字を許可)を取得=にマッチし、新しいのすべてをキャプチャすることですキー、またはラインの終わり

Check it out at regex101

関連する問題