文字という2つの一重引用符が含まれる文字列があります'
。一重引用符の間に、必要なデータがあります。
次のテキストから「必要なデータ」を抽出するための正規表現を作成するにはどうすればよいですか?
mydata = "some string with 'the data i want' inside";
文字という2つの一重引用符が含まれる文字列があります'
。一重引用符の間に、必要なデータがあります。
次のテキストから「必要なデータ」を抽出するための正規表現を作成するにはどうすればよいですか?
mydata = "some string with 'the data i want' inside";
一重引用符で囲まれた部分が必要な場合は、この正規表現をMatcher
:で使用します。
"'(.*?)'"
例:
String mydata = "some string with 'the data i want' inside";
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find())
{
System.out.println(matcher.group(1));
}
結果:
欲しいデータ
これには正規表現は必要ありません。
プロジェクトにapachecommonslangを追加し(http://commons.apache.org/proper/commons-lang/)、次を使用します。
String dataYouWant = StringUtils.substringBetween(mydata, "'");
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".*'([^']*)'.*");
String mydata = "some string with 'the data i want' inside";
Matcher matcher = pattern.matcher(mydata);
if(matcher.matches()) {
System.out.println(matcher.group(1));
}
}
}
これには簡単なワンライナーがあります:
String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");
一致するグループをオプションにすることで、この場合は空白を返すことで引用符が見つからない場合にも対応できます。
ライブデモをご覧ください。
Scalaにもチェックマークを付けたので、複数の引用符で囲まれた文字列を簡単に処理できる正規表現のないソリューション:
val text = "some string with 'the data i want' inside 'and even more data'"
text.split("'").zipWithIndex.filter(_._2 % 2 != 0).map(_._1)
res: Array[java.lang.String] = Array(the data i want, and even more data)
String dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1");
このバージョンでは、引数のない新しいメソッドを使用できます。これは、一致操作の結果を表し、一致したグループなどを読み取ることを提供する場所Matcher::results
を快適に返すことができます(このクラスはJava 1.5以降で知られています)。Stream<MatchResult>
MatchResult
String string = "Some string with 'the data I want' inside and 'another data I want'.";
Pattern pattern = Pattern.compile("'(.*?)'");
pattern.matcher(string)
.results() // Stream<MatchResult>
.map(mr -> mr.group(1)) // Stream<String> - the 1st group of each result
.forEach(System.out::println); // print them out (or process in other way...)
上記のコードスニペットは次のようになります。
the data I want another data I want
if (matcher.find())
最大の利点は、手続き型およびwhile (matcher.find())
チェックと処理と比較して、1つ以上の結果が利用可能な場合の使いやすさです。
javascriptのように:
mydata.match(/'([^']+)'/)[1]
実際の正規表現は次のとおりです。/'([^']+)'/
(別の投稿のように)貪欲でない修飾子を使用する場合は、次のようになります。
mydata.match(/'(.*?)'/)[1]
きれいです。
String dataIWant = mydata.split("'")[1];
ライブデモを見る
Apache Commons Langは、java.lang API用のヘルパーユーティリティのホスト、特に文字列操作メソッドを提供します。あなたの場合、開始と終了の部分文字列は同じなので、次の関数を呼び出すだけです。
StringUtils.substringBetween(String str, String tag)
同じ文字列の2つのインスタンスの間にネストされている文字列を取得します。
開始サブ文字列と終了サブ文字列が異なる場合は、次のオーバーロードされたメソッドを使用します。
StringUtils.substringBetween(String str, String open, String close)
2つの文字列の間にネストされている文字列を取得します。
一致する部分文字列のすべてのインスタンスが必要な場合は、次を使用します。
StringUtils.substringsBetween(String str, String open, String close)
文字列で開始タグと終了タグで区切られた部分文字列を検索 し、配列内の一致するすべての部分文字列を返します。
問題の例では、一致する部分文字列のすべてのインスタンスを取得します
String[] results = StringUtils.substringsBetween(mydata, "'", "'");
Scalaでは、
val ticks = "'([^']*)'".r
ticks findFirstIn mydata match {
case Some(ticks(inside)) => println(inside)
case _ => println("nothing")
}
for (ticks(inside) <- ticks findAllIn mydata) println(inside) // multiple matches
val Some(ticks(inside)) = ticks findFirstIn mydata // may throw exception
val ticks = ".*'([^']*)'.*".r
val ticks(inside) = mydata // safe, shorter, only gets the first set of ticks
これを使用すると、whileループを使用して、一致するすべてのサブストリングを配列に格納できます。
if (matcher.find())
{
System.out.println(matcher.group(1));
}
これを使用してすべての一致部分文字列を取得できるように、一致部分文字列を取得します
Matcher m = Pattern.compile("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+").matcher(text);
// Matcher mat = pattern.matcher(text);
ArrayList<String>matchesEmail = new ArrayList<>();
while (m.find()){
String s = m.group();
if(!matchesEmail.contains(s))
matchesEmail.add(s);
}
Log.d(TAG, "emails: "+matchesEmail);
pom.xmlにapache.commons依存関係を追加します
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
そして、以下のコードは機能します。
StringUtils.substringBetween(String mydata, String "'", String "'")
group(1)がうまくいかなかった理由。group(0)を使用してURLバージョンを検索しました。
Pattern urlVersionPattern = Pattern.compile("\\/v[0-9][a-z]{0,1}\\/");
Matcher m = urlVersionPattern.matcher(url);
if (m.find()) {
return StringUtils.substringBetween(m.group(0), "/", "/");
}
return "v0";