r"
#### NEGATIONS ####
#Busy ∂
\b(
#wrapper
(?:(?:from|is|i|am|at|on|it|do|to|for|a|make|the
|that|day|time|month|exactly
|call|meeting|lunch|breakfast|brunch)[ ])*
(?:
#negative words
(?:busy|can'?t|can[ ]?n?ot|unavailable|except)
#negated positive words
|(?:not|∆)[ ] (?:be|∆)?[ ]? (?:available|free|around|do|able)
)
#wrapper
[ ]?(?:(?:from|is|i|am|at|on|it|do|to|for|a|make|the
|that|day|time|month|exactly
|call|meeting|lunch|breakfast|brunch)[ ])*
#wrapper gets one free word
(?:[ ]? (?:\S+) [ ]?)?
#Repeat wrapper so free word can be anywhere in continuation
[ ]?(?:(?:from|is|i|am|at|on|it|do|to|for|a|make|the
|that|day|time|month|exactly
|call|meeting|lunch|breakfast|brunch)[ ])*
[ ]?(∂|then|at[ ]that[ ]time)
|
#∂ Busy
#reverse the above after everything else
∆
#am doing|at X at|on ∂
| ( ( (\b(?:am|are|will[ ]be)\b[ ])
(at|on|doing|\S+ing|OOO|out[ ]of[ ]office)[ ]
#"Have a" is a special case. Can't have "a" in the second group.
# | (?:have|has)[ ](?:an?)[ ]
#"Have a" also needs a negative lookahead for various false positives
# (?! .* (?:free|open|clean?r?|fresh|blank|vacant|bare|naked) )
#8 Free words, no \s\r\n or ".!?"
) (?:[^.• !?\r\n]+[ ]){0,8}
#may need to come back to the below, ?'d out for now
(?:at|on)?
)
(∂|then|at[ ]that[ ]time)
#REVERSE EXCEPT: "I am busy Tomorrow Except for 3-5pm"
#"I have a 3pm"
)
#busy ∂ (and also ∂) - NO ALTERNATION
[ ]? (?:(?:(?:and|maybe|also|aswell|as| [\.,?!:;] ) [ ])* (∂))?
#SAVIOUR STRINGS: Noone says "we can do X" after valid dates.They might: "We can also do X"
|
#"a" can't be the first word
(?!a)
#match continous strings made up of 2 groups of words
((?:(?:we|could|how|i|a|is|it|am|be|do|can|you|would)[ ])+ )
((?:(?:it|on|at|to|do|from
|have|can|able|make|about|free|exactly|say|call|take|possible|meet)[ ])+ )
(∂)
"
gmix