How to use lookahead to exclude special characters in a regular expression

You can skip grep and get this done in a single awk:

xrandr | awk 'NF >= 3 && /[0-9]+x[0-9]+/ {sub(/[+-].*/, "", $3); print $3}'


Alternative single gnu grep solution:

xrandr | grep -oP 'connected\h+\K(\d+x\d+|\S+)'

The (.*\d+x\d+)*^(?![\+]+\d\+\d) pattern matches and captures into Group 1 an optional sequence of any zero or more chars other than line break chars, as many as possible, then 1+ digits, x, 1+ digits, and then requires the start of string position (this makes the pattern fail all the time!) and makes sure there is no one or more + chars, a digit, a + and a digit immediately to the right of the current location. This looks like a very corrupt pattern that never matches any string.

Your logic can be implemented as

xandr | grep -oP '\b\d+x\d+(?!(?:\+\d+\+)?\d)'

See the online demo and the regex demo.


  • -oP - output matches only and enable PCRE regex engine
  • \b\d+x\d+(?!(?:\+\d+\+)?\d):
    • \b - word boundary
    • \d+ - one or more digits
    • x - an x
    • \d+ - one or more digits
    • (?!(?:\+\d+\+)?\d) - a negative lookahead that fails the match if, immediately to the right of the current location, there is
    • (?:\+\d+\+)? - an optional sequence of +, one or more digits and +
    • \d - a digit.