10

Say it's very easy if I want to find something containing lower-case letters and numbers with

produce_text | grep -E '[0-9a-z]'

Brackets are useful to match a set of characters, but what about those that are somewhat special?
If I want to, using brackets, match any character but one of these: a closing bracket ], a dash (or hyphen) "-", both slashes / and \, a caret ^, a colon :.
Will it look like this (I know this doesn't work)?

[^]-/\^:]
11

To match a literal ] and a literal - in a Bracket Expression you'll have to use them like this:

[^]/\^:-]

or, even better, since some tools require the backslash to be escaped:

[^]/\\^:-]

that is
The right-square-bracket ( ']' ) shall lose its special meaning and represent itself in a bracket expression if it occurs first in the list (after an initial '^', if any)
and
The hyphen-minus character shall be treated as itself if it occurs first (after an initial '^', if any) or last in the list
hence
If a bracket expression specifies both '-' and ']', the ']' shall be placed first (after the '^', if any) and the '-' last within the bracket expression.
The rules for bracket expressions are the same for ERE and BRE.

  • 2
    I'd double the backslash to be on the safe side. It's needed with many awk implementations and perl for instance. – Stéphane Chazelas Feb 5 '17 at 1:58
  • What about "From caret to closing bracket"? Like [^-]] (This one fails)? – iBug Feb 6 '17 at 23:02
  • 2
    @iBug - sure it fails as the right bracket has to be first if you want to match it literally. I'm not sure I get the point of that "range" that you mention as ^ is after ] so [^-]] would not work even if both ^ and ] were treated literally (just like [b-a]). Anyway, if you wanted to match from e.g. ; to closing bracket you could use a range up to the char before ] (which is backslash) and include ] as first char in the bracket expression so e.g. [];-\\]. – don_crissti Feb 6 '17 at 23:41
  • @don_crissti What about [[.^.]-[.-.]]? I have a feeling that this would work. Let's assume that the ASCII code of ^ is before -. – iBug Feb 7 '17 at 13:48
  • Got a lazy solution for my question. Simply get everything special to collating characters, like [^[.].][.-.]/\^:] – iBug Feb 7 '17 at 13:55
7

Strangely perhaps, you need to have a couple of characters in specific places. You must have ] as the first character in a set, and - must be the last character in a set.

Here is an RE that meets your requirements: [^]\^/-]:

echo 'Hello[world]-[sun] ^^ 4/5 or 3\4' | grep -Eo '[^]\^/-]' | xargs
H e l l o [ w o r l d [ s u n 4 5 o r 3 4
  • 1
    It's not really strange, it's just necessary to avoid ambiguity – Kevin Feb 4 '17 at 18:24
  • 1
    The second [ character doesn't belong there; the OP doesn't want to exclude it. – Scott Feb 5 '17 at 1:53
  • @Scott well spotted, thank you. Answer updated. – roaima Feb 14 '17 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.