java.lang.IndexOutOfBoundsException: No group 1 | Pattern matching

14,155

Solution 1

It'd advise against (ab)using look-behind, if it is possible to write one without that is clear and does the same thing.

Just use the pattern:

version=(.*)

And what you want will be in capturing group 1.

Solution 2

The code is using lookbehind assertion:

(?<=version=)

That is not captured as a group. If you want capture version= as a group, use capturing group:

(version=)

To get 1.1 from the given string input, use following regular expression:

(?<=version=)(.*)
Share:
14,155
Vaibhav Raj
Author by

Vaibhav Raj

Software Engineer having hands on experience with Java, Spring framework, Hibernate, Mongodb, Redis, Mysql, Elasticsearch ....

Updated on June 05, 2022

Comments

  • Vaibhav Raj
    Vaibhav Raj almost 2 years

    I am trying to extract the value of version from Accept header which can be of the form

    "vnd.example-com.foo+json; version=1.1" 
    

    here is my code for extracting the version

    val resourceVersionPattern: Pattern = Pattern.compile("(?<=version=).*")
    
    def getResourceVersion(acceptHeader: String): String = {
                import java.util.regex.Matcher
                val matcher: Matcher = resourceVersionPattern.matcher(acceptHeader)
                if(matcher.find()) ("v" + matcher.group(1)).trim() else "v1.0"
        }
    

    When I am invoking the above function which is intended to extract version (for example can be of the form v1.0 or v1.5 or v2.5)

     getResourceVersion("vnd.example-com.foo+json; version=1.1")
    

    I get following exception:

    java.lang.IndexOutOfBoundsException: No group 1
    at java.util.regex.Matcher.group(Matcher.java:487)
    at .getResourceVersion(<console>:12)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:744)
    

    I think I am doing something wrong in my regex or the input string has some illegal charecters which I am not able to identify with my limited knowledge of Regular expression. Help me find out the reason.

  • Vaibhav Raj
    Vaibhav Raj about 10 years
    After modifying the pattern as (?<=(version=)) what I get after making the call getResourceVersion("vnd.example-com.foo+json; version=1.1") is vversion= not v1.1. I want to extract the version number and add v as a prefix to it. Is my pattern correct?
  • falsetru
    falsetru about 10 years
    @VaibhavRaj, Try (?<=version=)(.*).
  • Alan Moore
    Alan Moore about 10 years
    Simply changing group(1) to group() will fix the problem; you don't need to add any parentheses. group() is equivalent to group(0), which returns everything that was consumed by the match. (The "version=" part is not consumed because it was matched in a lookbehind.) But nhahtdh's solution is better.
  • Alex Wittig
    Alex Wittig about 10 years
    @AlanMoore You're right, that's what I was trying to say but was not very clear.
  • dukemalik
    dukemalik about 10 years
    "(?<=(version=))(\\d((\\.)(\\d)+)?)" this one is better one work for all type string 1. version=1.asdfa 2. version=1.234asaf 3. version=1.1 4. version=1.1 afasd