如何使用正则表达式提取子字符串


382

我有一个字符串,其中有两个单引号,即'字符。在单引号之间是我想要的数据。

如何编写正则表达式从以下文本中提取“我想要的数据”?

mydata = "some string with 'the data i want' inside";

Answers:


569

假设您想要单引号之间的部分,请将此正则表达式与一起使用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));
}

结果:

我想要的数据

12
该死的..我总是忘了非贪婪的修饰符:(
Mihai Toader

33
如果您预计会发生多次,请用“ while”替换“ if”
OneWorld 2012年

14
请注意,此代码示例需要使用matcher.find()。调用matcher.group(1)时,未能调用此方法将导致“找不到匹配项”异常。
rexford 2014年

25
@mFontoura group(0)将返回与外部''的完整匹配。group(1)返回''中间的内容,而不返回''本身。
tagy22

6
@Larry这是一个较晚的答复,但是?在这种情况下是非贪婪的修饰符,因此this 'is' my 'data' with quotes它会提前停止并返回,is而不是匹配尽可能多的字符并返回is' my 'data,这是默认行为。
Timekiller

68

您不需要正则表达式。

将apache commons lang添加到您的项目(http://commons.apache.org/proper/commons-lang/),然后使用:

String dataYouWant = StringUtils.substringBetween(mydata, "'");

12
您必须考虑如何分发您的软件。如果是Webstart之类的东西,那么仅使用此功能添加Apache Commons是不明智的。但也许不是。此外,Apache Commons还提供了许多其他功能。即使很难知道正则表达式,您也必须谨慎使用它。正则表达式可能很难阅读,编写和调试。在某些情况下,使用它可能是更好的解决方案。
Beothorn

3
有时StringUtils已经存在,在这种情况下,此解决方案更加清晰易读。
加博·纳吉

7
就像买一辆汽车行驶5英里(一年只旅行一次)一样。
祈祷

子字符串查找特定的字符串或值,而正则表达式查找格式。它越来越动态。如果要查找模式而不是特殊值,则需要正则表达式。
burakhan alkan

14
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));
        }

    }
}

2
System.out.println(matcher.group(0)); <-零
基索

4
编号group(0)具有特殊含义,捕获组从索引group(1)开始(即答案中的group(1)是正确的)。“捕获组是从左至右,开始于一个索引零组表示整个模式。” -来源:docs.oracle.com/javase/8/docs/api/java/util/regex/...
先验

12

有一个简单的方法:

String target = myData.replaceAll("[^']*(?:'(.*?)')?.*", "$1");

通过使匹配组为可选,这还可以通过在这种情况下返回空白来解决找不到引号的问题。

观看现场演示


10

因为您还勾选了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)

4
如此可读的解决方案,这就是为什么人们喜欢scala,我相信自己是这样的:)
祈祷的人,

3
为什么不只是.split('\'').get(2)Java或某种程度的Java?我认为,如果您认为这是一种可读的解决方案,则可能需要进行脑部扫描-好像有人试图向我打些代码。
ArtOfWarfare

7
String dataIWant = mydata.replaceFirst(".*'(.*?)'.*", "$1");

4

如在javascript中:

mydata.match(/'([^']+)'/)[1]

实际的正则表达式为: /'([^']+)'/

如果您使用非贪婪修饰符(根据另一篇文章),则如下所示:

mydata.match(/'(.*?)'/)[1]

它更干净。


2

在斯卡拉,

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


1

Apache Commons Lang为java.lang API提供了许多帮助程序实用程序,最著名的是String操纵方法。在您的情况下,开始和结束子字符串相同,因此只需调用以下函数即可。

StringUtils.substringBetween(String str, String tag)

获取嵌套在同一String的两个实例之间的String

如果开始和结束子字符串不同,则使用以下重载方法。

StringUtils.substringBetween(String str, String open, String close)

获取嵌套在两个字符串之间的字符串。

如果您想要所有匹配子字符串的实例,请使用,

StringUtils.substringsBetween(String str, String open, String close)

在字符串中搜索以开始和结束标记分隔的子字符串, 并返回array中所有匹配的子字符串

对于有问题的示例,获取匹配子字符串的所有实例

String[] results = StringUtils.substringsBetween(mydata, "'", "'");

0

您可以使用它,我使用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);

0

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 "'")

0

该小组(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";
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.