Java Question Difference in treatment of Regex between Java 1.7 and Android?

Discussion in 'Libraries developers questions' started by keirS, Mar 9, 2015.

  1. keirS

    keirS Well-Known Member Licensed User

    I hate Regex. The following Java code runs fine in Eclipse.

    Code:
    public static void main(String[] args) {
            // TODO Auto-generated method stub
      final Pattern validstatement  =   Pattern.compile(
    "^\\s*\\{?\\s*(\\?\\s*=)?\\s*call\\s*([\\w.]+)(\\(.*\\))?\\s*}?", Pattern.CASE_INSENSITIVE);
        
    Matcher m = validstatement .matcher("{ call order(?, ?) }");
        
    if(m.matches()) {
            System.out.println(
    "Valid");
        
    } else {
            System.out.println("Invalid");
        }
        }

    }
    }

    In B4A
    Code:
    Regex.IsMatch("^\\s*\\{?\\s*(\\?\\s*=)?\\s*call\\s*([\\w.]+)(\\(.*\\))?\\s*}","{ call order(?,?) }")
    I get.
    Code:
    java.util.regex.PatternSyntaxException: Error in {min,max} interval near index 9:


    ^\\s*\\{?\\s*(\\?\\s*=)?\\s*call\\s*([\\w.]+)(\\(.*\\))?\\s*}
             ^
        at java.util.regex.Pattern.compileImpl(Native Method)
        at java.util.regex.Pattern.compile(Pattern.java:411)
        at java.util.regex.Pattern.<init>(Pattern.java:394)
        at java.util.regex.Pattern.compile(Pattern.java:374)
        at anywheresoftware.b4a.keywords.Regex.getPattern(Regex.java:34)
        at anywheresoftware.b4a.keywords.Regex.IsMatch2(Regex.java:60)
        at anywheresoftware.b4a.keywords.Regex.IsMatch(Regex.java:53)
        at b4a.example.main._activity_create(main.java:341)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
        at b4a.example.main.afterFirstLayout(main.java:100)
        at b4a.example.main.access$100(main.java:17)
        at b4a.example.main$WaitForLayout.run(main.java:78)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

    Not too surprising that i get the same thing in a library. So why the difference?
     
  2. thedesolatesoul

    thedesolatesoul Expert Licensed User

    That is overly weird regex. I dont understand why you need double slashes.
    Just use one slash to escape the curly brace and even the \s should just have one slash.
     
  3. keirS

    keirS Well-Known Member Licensed User

    It's not my library! Anyway a bit of time and effort and using Erel's most helpful online B4J Regex tool I worked out the correct Regex expression:

    Code:
    ^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*}
    Scrap the above. This works in B4J but not in B4A.

    I have to escape the } at the end in B4A

    Code:
    ^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*\}
    [code]
     
    Last edited: Mar 9, 2015
  4. thedesolatesoul

    thedesolatesoul Expert Licensed User

    I dont know what library you are talking about and it doesnt really matter.

    Your corrected regex is exactly what i said, no double slashes.
     
  5. keirS

    keirS Well-Known Member Licensed User

    The library is a JDBC driver. So it's a bit worrying that it looks like it will not work with B4J or B4A out of the box.
     
  6. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Do you need to pasd the regex to the library?
    Where is the matching done?
     
  7. keirS

    keirS Well-Known Member Licensed User

    The Regex's are in the JDBC library. It's open source so see here for an example of the code where the RegEx's crash.

    This is one example
    Code:
    static Pattern PARAMETER_PATTERN =. Pattern.compile("\\s*(IN\\s+|OUT\\s+|INOUT\\s+)?([\\w\\d]+)\\s+(UNSIGNED\\s+)?(\\w+)\\s*(\\([\\d]+\\))?\\s*",  Pattern.CASE_INSENSITIVE);
     
  8. thedesolatesoul

    thedesolatesoul Expert Licensed User

  9. Erel

    Erel Administrator Staff Member Licensed User

    This is the correct answer. In java you need to escape slashes so there are double slashes in the Java code.
     
  10. keirS

    keirS Well-Known Member Licensed User

    Erel that doesn't explain why this Regex works in B4J

    Code:
    ^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*}
    Burt crashes in B4A.

    Code:
    If Regex.IsMatch("^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*}","{ call order(?,?) }"Then
             
    Log("match")
      
    End If

    Code:
    java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 54:
    ^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*
    }
                                                                             ^
        at java.util.regex.Pattern.compileImpl(Native Method)
        at java.util.regex.Pattern.compile(Pattern.java:411)
        at java.util.regex.Pattern.<init>(Pattern.java:394)
        at java.util.regex.Pattern.compile(Pattern.java:374)
        at anywheresoftware.b4a.keywords.Regex.getPattern(Regex.java:34)
        at anywheresoftware.b4a.keywords.Regex.IsMatch2(Regex.java:60)
        at anywheresoftware.b4a.keywords.Regex.IsMatch(Regex.java:53)
        at b4a.example.main._activity_create(main.java:341)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
        at b4a.example.main.afterFirstLayout(main.java:100)
        at b4a.example.main.access$100(main.java:17)
        at b4a.example.main$WaitForLayout.run(main.java:78)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
    ~e:    at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    Try to escape the last bracket:
    Code:
    Regex.IsMatch("^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*\}""Asdasd")
    Seems like a difference between Oracle Java behavior and Google Android Java behavior.
     
    thedesolatesoul likes this.
  12. keirS

    keirS Well-Known Member Licensed User

    I am trying to use a third party Java library so it doesn't solve my problem. Is there anyway of including the Regex classes from Java in a Jar and telling the Android JVM to use those classes instead of the inbuilt ones?
     
  13. thedesolatesoul

    thedesolatesoul Expert Licensed User

    It doesnt matter. You seem to be focused on the wrong thing. Your regex expression was invalid as the last bracked was not escaped.
     
    NJDude likes this.
  14. keirS

    keirS Well-Known Member Licensed User



    No I am focused on the right thing. Code from the library.

    Code:
    static Pattern CALLABLE_STATEMENT_PATTERN = Pattern.compile("^\\s*\\{?\\s*(\\?\\s*=)?\\s*call\\s*([\\w.]+)(\\(.*\\))?\\s*}?", Pattern.CASE_INSENSITIVE)
    That's not my Java code it's code in the JDBC driver library. Code which doesn't work in Android but works in regular Java because regular Java accepts "}" as being valid but Android expects "/}".
     
  15. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Its very frustrating as the information you provide is trickling down like tiny drops of water.
    Are you going to give us the full picture or not?
    Where is the source of this jdbc driver and where did you pick it up from? How do you know it is compatible with Android? Where is the documentation?
     
    NJDude likes this.
  16. keirS

    keirS Well-Known Member Licensed User

    It's doesn't say it's not compatible; I thought the whole point of Java was it's portability? I have used portions of the library successfully for well over 2 years in Android as have other forum members. I downloaded the latest release using Maven. The repository is here for both the .Jar, source and JavaDoc.
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    No. You cannot replace native classes.
     
    keirS likes this.
  18. keirS

    keirS Well-Known Member Licensed User

    OK. Thanks Erel.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice