Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正则表达式用于识别组_Java_Regex - Fatal编程技术网

Java 正则表达式用于识别组

Java 正则表达式用于识别组,java,regex,Java,Regex,我有以下字符串 @name Home @options {} @include h1,h2,h3 @exclude p,div,em 我想按正则表达式进行拆分,并将其存储在HashMap中 @name->Home @options->{} @include->h1,h2,h3 @exclude->p,div,em 我使用了下面的正则表达式,但它与@name后面的整个字符串相匹配 import java.util.regex.Matcher; import java.u

我有以下字符串

@name Home @options {} @include h1,h2,h3 @exclude p,div,em
我想按正则表达式进行拆分,并将其存储在
HashMap

@name->Home
@options->{}
@include->h1,h2,h3
@exclude->p,div,em
我使用了下面的正则表达式,但它与@name后面的整个字符串相匹配

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NewClass {

    public static void main(String[] args) {
        String regex = "((?<var>@(\\S)+) (?<val>.+) *)+";

        String val = "@name Home @options {} @include h1,h2,h3 @exclude p,div,em";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(val);
        if (matcher.matches()) {
            System.out.println(matcher.group("var"));
            System.out.println(matcher.group("val"));
        }
    }
}

正则表达式的问题在于,您不知道输入中的组数,即有多少
@xxx
组。因此,您需要多次应用正则表达式,即使用while循环和
matcher.find()

也就是说,您的正则表达式只需要匹配一个组,并且假设在输入的第一个
@
到下一个或结尾之间没有其他匹配。因此,表达式可以变成
(?@(\S)+)(?[^@]+)

该表达式基本上由两部分组成,中间只有一个空格(您可能希望将其改为
\s+

  • (?@(\S)+
    匹配以
    @
    开头的组名,并以任何非空白的内容继续。请注意,此处不需要内部组,因此只需使用
    \S+
    -除非要提取不带
    @
    的名称
  • (?[^@]+)
    匹配至少一个非
    @
    字符的任何序列,即下一个
    @
    或输入末尾的任何字符。请注意,您不会以这种方式匹配空组,因此如果您也想匹配这些字符,您可能需要将量词改为
    *
    • 那么:

      (@[^@]+)
      

      请参阅。

      为什么对所有内容都使用正则表达式

      只是说:一个简单的解析器,只要在“@”上进行拆分,可能会导致代码更容易理解

      这将产生一个数组“var value”;在这里,您只需将第一个空格后面的子字符串作为值

      你看,你需要其他人拿出一个“正确”的正则表达式。这可能意味着每次你想增强/返工/更新该正则表达式时,你都必须求助于其他人。

      使用正则表达式,而不是
      。匹配需要完整字符串匹配的
      ,使用
      while(matcher.find())

      String regex=“(?@\\S+)\\S+(?\\S+)”;
      String val=“@name Home@options{}@include h1、h2、h3@exclude p、div、em”;
      Pattern=Pattern.compile(regex);
      Matcher-Matcher=pattern.Matcher(val);
      Map m=新的HashMap();
      while(matcher.find()){
      m、 put(matcher.group(“var”)、matcher.group(“val”);
      }
      System.out.println(m);//=>{@name=Home,@exclude=p,div,em,@include=h1,h2,h3,@options={}
      

      请参阅

      @Madhan它在Java中工作,但只提供了一个未命名的捕获组,然后您必须将其分离以获取键值对。@Aaron只是对循环的改进版本的一个评论,因为我感觉您没有意识到:
      [^\s]
      \s
      (大写在大多数情况下定义了否定的速记类)。@Thomas谢谢,我更新了ideone代码段。我知道否定类,但往往忘记使用它们:)
      while (matcher.find()) {
        System.out.println(matcher.group("var"));
        System.out.println(matcher.group("val"));
      }
      
      (@[^@]+)
      
      String regex = "(?<var>@\\S+)\\s+(?<val>\\S+)";
      String val = "@name Home @options {} @include h1,h2,h3 @exclude p,div,em";
      Pattern pattern = Pattern.compile(regex);
      Matcher matcher = pattern.matcher(val);
      Map<String, String> m = new HashMap<String, String>();
      while (matcher.find()) {
          m.put(matcher.group("var"), matcher.group("val"));
      }
      System.out.println(m); // => {@name=Home, @exclude=p,div,em, @include=h1,h2,h3, @options={}}