-1

I want to check given logical formulars with a regular expression.
The logical connectives for this form are & (and) , | (or), (!) negation sign (multiple negations allowed) and the variables are normal character sequences followed with cardinalities [0],[1],[0..1].
the variable names can also something be like this "F.G.H." or "F:G:H:" or simple "F" etc.
the square brackets belongs to the cardinalites.,lso constants are allowed,
e.g. with this pattern it is not working:

Pattern.compile("([!]*[a-zA-Z][\\.])?([!]*[a-zA-Z][\\.]?)*((\\[0\\])?|(\\[1\\])?|(\\[0\\.\\.1\\])?)|(TRUE)|(FALSE)|(&)|(|)|(!)"); my current case that a variable like this: !!F[0] is not accepted, but i want this to be accepted.

here some examples for the formulars, which i want to allow

!!F[0] & !F1.G[0..1] | (F1[1] | F2[0]) & F:G[0..1]

also whitespaces between each element, except variables and their cardinalities shall be allowed.

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
lunatikz
  • 716
  • 1
  • 11
  • 27
  • 1
    Are you sure that a regex is the best way to go? It seems to me you want to parse the expression anyway, so your parser can throw an error if the expression is invalid. – Sjoerd Aug 07 '12 at 14:22
  • i thought it would be the best way, better than many if statements for the single characters. I think using regular expressions is quite an elegant way to achieve this – lunatikz Aug 07 '12 at 14:23
  • also if iam parsing the formula, i have to parse each char element, so it could be difficult to ensure that some like this |.& is not allowed...the original type of the formular is a string object – lunatikz Aug 07 '12 at 14:27
  • You seem to have parenthetical expressions in your desired allowed state. Are nested parenthetical expressions allowed? If so then a regex is probably not the answer. See http://stackoverflow.com/questions/133601/can-regular-expressions-be-used-to-match-nested-patterns – Charlie May 24 '13 at 11:49
  • @lunatikz, If you want to check if a formula is valid or not, or even worse evaluate it, you must write a parser, e.g. http://www.antlr.org/ http://www.dabeaz.com/ply/ https://code.google.com/p/javaparser/ – Patashu May 24 '13 at 13:41

1 Answers1

1

This one is quite awful but should suit your needs:

[!(]*([A-Z]+[0-9]*([.:][A-Z]+[0-9]*)*\[([01]|0[.]{2}1)\]|TRUE|FALSE)[)]*( *[&|] *[!(]*([A-Z]+[0-9]*([.:][A-Z]+[0-9]*)*\[([01]|0[.]{2}1)\]|TRUE|FALSE)[)]*)*

Demo

Please note that is simply allows parentheses without counting them, i.e. inputs such as !((!(F[0]) will match while only !((!(F[0]))) should.


If you want something already cleaner, you could build your regex step by step:

String atomVarPref = "[!(]*";
String atomVar = "[A-Z]+[0-9]*";
String atomSep = "[.:]";
String atomVarCard = "\\[([01]|0[.]{2}1)\\]";
String atomVarSuff = "[)]*";
String sep = " *[&|] *";

String varTemplate = "%s(%s(%s%s)*%s|TRUE|FALSE)%s";
String var = String.format(varTemplate, atomVarPref, atomVar, atomSep, atomVar, atomVarCard, atomVarSuff);

String regexTemplate = "%s(%s%s)*";
String regex = String.format(regexTemplate, var, sep, var);

Calling:

String input = "!!F[0] & !F1.G[0..1] | (F1[1] | F2[0]) & F:G[0..1]";
System.out.println(input.matches(regex)); // prints true
sp00m
  • 47,968
  • 31
  • 142
  • 252