Search code examples
javaregexabort

Regex, How to abort at first fail?


I have the following string:

 "xya", "yyy", "zzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)

I'm trying to write a regex that keeps the user from inserting the wrong input (pretty much like a compiler isn't it?).

The first thing I'm trying to match is the "xya". Inside this double-quotes group can only exists letters x/y/z or whitespace with no more than 3 characters inside. So a valid input would be: "xxx" or "xyz" or "x " (yes, this is a Minecraft recipe).

This is the regex I have so far:

\s*([\"][xyz]{3}[\"][,])

It matches , "yyy", and "zzz",, but I want it to abort because "xya" is not a valid input, but the engines keeps searching through all the string.

I'm using Rad Software Regular Expression Designer to test my regex first.


Solution

  • If you want to immediately abort at a fail, how about doing a search for bad input instead? The following searches for entries that didn't meet your criteria (more than three characters, non x/y/z, null):

    "(|[\w\s]{4,}|[\w]{0,2}[^xyz][\w]{0,2})"
    

    Some examples of catching bad input:

    $ grep -P '"(|[\w\s]{4,}|[\w]{0,2}[^xyz][\w]{0,2})"' user_input.txt
    "xya", "yyy", "zzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "xxxx", "yyy", "zzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "xxx", "yag", "zzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "xxx", "yyy", "zzo",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "(", "yxy", "yzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "", "yxy", "yzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    

    An example of seeing what doesn't match (i.e. good input):

    $ grep -vP '"(|[\w\s]{4,}|[\w]{0,2}[^xyz][\w]{0,2})"' user_input.txt
    "xxx", "yyy", "zzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)
    "x", "yxy", "yzz",  'x', new ItemStack(Item.stick, 1, 0) , 'y', new ItemStack(Item.stick, 1, 0) , 'z', new ItemStack(Block.stone, 1, 0)