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

keirS

Well-Known Member
Licensed User
I hate Regex. The following Java code runs fine in Eclipse.

B4X:
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
B4X:
Regex.IsMatch("^\\s*\\{?\\s*(\\?\\s*=)?\\s*call\\s*([\\w.]+)(\\(.*\\))?\\s*}","{ call order(?,?) }")
I get.
B4X:
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?
 

keirS

Well-Known Member
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.
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:

B4X:
^\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

B4X:
^\s*\{\s*?\s*(\??\s*=?)\s*call\s*([\w.]+)\(.*\)\)?\s*\}
[code]
 
Last edited:

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.
 

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
B4X:
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);
 

thedesolatesoul

Expert
Licensed User

keirS

Well-Known Member
Licensed User
This is the correct answer. In java you need to escape slashes so there are double slashes in the Java code.
Erel that doesn't explain why this Regex works in B4J

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

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

B4X:
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)
 

keirS

Well-Known Member
Licensed User
Try to escape the last bracket:
B4X:
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.
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?
 

thedesolatesoul

Expert
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?
It doesnt matter. You seem to be focused on the wrong thing. Your regex expression was invalid as the last bracked was not escaped.
 

keirS

Well-Known Member
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.


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

B4X:
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 "/}".
 

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?
 

keirS

Well-Known Member
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?
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.
 
Top