我有一个包含两个单引号字符'
的字符串。在两个单引号之间的是我想要的数据。
我如何编写正则表达式从以下文本中提取出"the data i want"?
mydata = "some string with 'the data i want' inside";
我有一个包含两个单引号字符'
的字符串。在两个单引号之间的是我想要的数据。
我如何编写正则表达式从以下文本中提取出"the data i want"?
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));
}
结果:
我想要的数据
你不需要使用正则表达式。
将Apache Commons Lang添加到您的项目中(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));
}
}
}
matches()
尝试匹配整个字符串,因此如果您的模式开头和结尾没有 ".*",它将找不到任何内容。 - oneturkmen这可以用一个简单的一行命令来实现:
String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");
通过使匹配组可选,也能满足当引号不存在时返回空白的情况。
请参见演示。
从这个版本开始,你可以使用一个新的方法Matcher::results
,该方法不带参数并能够轻松返回Stream<MatchResult>
,其中MatchResult
表示匹配操作的结果,并提供读取匹配组等功能(此类从Java 1.5版本就已知)。
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())
检查和处理。因为您还选择了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)
.split('\'').get(2)
或类似的方式呢?如果你认为这是可读的解决方案,我想你可能需要做一次脑部扫描 - 对我来说,它看起来像有人试图进行代码高尔夫比赛。 - ArtOfWarfareString dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1");
replaceFirst
?为什么是 $1
? - Elikill58.*'
匹配第一个'
之前的所有内容,包括'
,而'.*
匹配之后的所有内容。(.*?)
是一个非贪婪地捕获两个引号之间的所有内容的组,我想。$1
表示我们想要用正则表达式匹配到的内容(在这种情况下是所有内容)替换为第一个捕获组的内容((.*?)
匹配两个引号之间的所有内容)。$0
将意味着整个正则表达式。 - undefined就像JavaScript中一样:
mydata.match(/'([^']+)'/)[1]
实际的正则表达式是:/'([^']+)'/
如果您使用非贪婪修饰符(如另一篇文章所述),则应该像这样:
mydata.match(/'(.*?)'/)[1]
它更加干净。
String dataIWant = mydata.split("'")[1];
请参考演示示例
这段代码的意思是从mydata字符串中获取单引号内的数据并将其存储在dataIWant变量中。Apache Commons Lang提供了许多java.lang API的辅助工具,最主要的是字符串操作方法。 在您的情况下,起始和结束子字符串相同,因此只需调用以下函数。
如果起始和结束子字符串不同,则使用以下重载方法。StringUtils.substringBetween(String str, String tag)
Gets the String that is nested in between two instances of the same String.
如果您想要匹配所有子字符串的实例,则使用以下命令:StringUtils.substringBetween(String str, String open, String close)
Gets the String that is nested in between two Strings.
StringUtils.substringsBetween(String str, String open, String close)
Searches a String for substrings delimited by a start and end tag, returning all matching substrings in an array.
针对此示例,获取所有匹配子字符串的实例
String[] results = StringUtils.substringsBetween(mydata, "'", "'");