7

I am on a closed network (i.e. no connectivity to the internet).

I have a bourne shell script that asks for the user to enter a regular expression for use with grep -P.

Generally speaking, I like to do some form of input validation.
Is there a way to test a string variable to see if it is a (valid) regex?
(Copying things from the internet onto my system can be done, but it takes forever and is a PITA -- thus I am looking for way to do it natively.)

8
  • 3
    What do you mean by "valid regex"? What's an invalid regex?
    – muru
    Mar 22, 2023 at 23:34
  • 4
    And you mean actual bourne shell right, not bash?
    – terdon
    Mar 23, 2023 at 12:38
  • 1
    bash is Bourne-again shell, and is far more featureful than the Bourne shell
    – phuclv
    Mar 23, 2023 at 13:05
  • natively... grep already isn't a native a part of your shell, but an external tool. Granted, it's a standard one, and so likely to be found anywhere, but then again e.g. Debian-based systems always have Perl too, so what tools you have really depends on the system. If you're on Linux, you likely have either Bash or some smaller POSIX-only shell, like Dash or Busybox, not an ancient Bourne shell. (Note the bourne-shell tag has the description "a historical implementation of /bin/sh")
    – ilkkachu
    Mar 23, 2023 at 16:32
  • @terdon: Yes, /bin/sh, not /bin/bash.
    – Scottie H
    Mar 28, 2023 at 18:21

1 Answer 1

19

No, but with some tools it's not hard to test whether a regex compiles or not.

For example, with grep: echo | grep -P '[' - the exit code, $?, will be 2, indicating an error occurred (and for this example, grep will print "grep: missing terminating ] for character class" to stderr - you can redirect stderr to /dev/null if you only want the exit code).

An exit code of 1 indicates that the regex compiled OK but didn't match the input.

These exit codes are specific to GNU grep. Other tools, if they even have such a capability, will probably have different exit codes, and different ways of indicating specific kinds of errors.

Note that this is not even remotely close to telling you whether a regex will correctly match what you want it to (and not match what you don't want it to).

In short, try it and test the exit code. And know your tools.

17
  • 5
    @terdon yep, i considered adding a note with that example (actually, grep . nosuchfile) but, in the context of piping an empty line into grep, that's never going to happen (ditto for perms errors), so I cut it. As you say, an exit code of 2 in GNU grep doesn't mean "regex error", it just means "error". However, in this context, there isn't anything else it can be (except perhaps OOM or maybe a pipe error due to lack of resources or something else arising from a far bigger system problem - e.g. CPU or RAM fault - that's way beyond the scope of a simple method to check the validity of an RE)
    – cas
    Mar 23, 2023 at 13:10
  • 4
    I don't think there's any need for the pipeline here - just take input from the null device: grep "$re" /dev/null 2>/dev/null. If /dev/null doesn't exist, you have Bigger Problems! (Minor aside: my versions of GNU grep - 3.6 and 3.8 - have a different error message. It's just "grep: Invalid regular expression" which isn't quite as informative as yours). Mar 23, 2023 at 13:55
  • 2
    @TobySpeight, since I happened to test, redirecting from /dev/null doesn't seem to work with Busybox, e.g. busybox grep -e '[' < /dev/null just exits with status 1 without a comment. It looks like it doesn't bother to compile the regex if there's no input. I wouldn't have expected that choice, but it's not exactly wrong, as the empty input has nothing to match anyway.
    – ilkkachu
    Mar 23, 2023 at 16:35
  • 2
    @ilkkachu Right. The test should be $? -gt 1 rather than $? -eq 2
    – Barmar
    Mar 23, 2023 at 17:03
  • 3
    I remember using an ancient grep. There weren't any invalid regexes. The unclosed class for example would be force-reinterpreted as a literal [.
    – Joshua
    Mar 23, 2023 at 18:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .