Based on my SO question, but more specifically:

Find a RegEx such that, given a text where paragraphs end with an empty line (or $ at the very end), match the up to twenty last characters of a paragraph excluding the \r or $ but no more than three complete "words" including the "separators" in between and the punctuation following it. The following constraints apply:

  • "words" also include abbreviations and the like (and thus punctuation), i.e. "i.e." and "non-trivial" count as one word each
  • whitespaces are "separators"
  • isolated dashes do not count as "words" but as "separators"
  • "separators" before the first word must not be included
  • trailing punctuation counts to that limit, but not the leading one nor the linebreaks and $ that must not be in the matching group
  • whether trailing punctuation is included in the match or not is up to you

Some examples:

The early bird catches the worm. Two words.

But only if they got up - in time.

Here we have a supercalifragilisticexpialidocious etc. sentence.

Short words.

Try accessing the .html now, please.

Vielen Dank und viele Grüße.

Did any-one try this?

Score is given in bytesteps: bytes multiplied by amount of steps according to https://regex101.com, but there are three penalties:

  • if the upper limit of words cannot trivially+ be modified: +10%
  • if the upper limit of character count cannot trivially+ be modified: +10%
  • failure to handle unicode used in actual words: add the percentage of world population speaking the language according to Wikipedia the failing word stems from. Example: Failing to match the German word "Grüße" as a word => +1.39%. Whether you consider a language's letters as single characters or count the bytes to utf8-encode them is up to you. The penalty does not have to be applied before someone actually provides a counter-example, so feel free to demote your competitors ;)

Since this is my first challenge, please suggest any clarifications. I assume means there are no "loopholes" to exclude.

+ With trivially modified I mean expressions such as {0,2} and {21} are valid but repeating something three times (which would have to be re-repeated to increase the amount words) is not.

  • \$\begingroup\$ Bonuses and penalties are generally disliked in challenges. And, while it makes sense to restrict this to regular expressions, why not remove the tag and let other languages compete as well? \$\endgroup\$ Commented May 19, 2016 at 9:21
  • 2
    \$\begingroup\$ @VTCAKAVSMoACE I assume because it's not just scored by bytes but also by the number of steps executed by the regex engine, which doesn't make sense for arbitrary languages. \$\endgroup\$ Commented May 19, 2016 at 9:22
  • \$\begingroup\$ Could you add test cases where a) there's leading punctuation, b) there's a hyphen that isn't surrounded by whitespace c) a paragraph that consists only of one of two words taking up much less than 20 characters? \$\endgroup\$ Commented May 19, 2016 at 9:24
  • \$\begingroup\$ Also the penalties aren't entirely clear. Of course the upper limit of words and characters can always be modified, it's just a question of how many places need to be changed. Do you mean 3 and 20 should appear as numbers in a single place which can be changed? \$\endgroup\$ Commented May 19, 2016 at 9:25
  • \$\begingroup\$ Will \s\s+ ever match the paragraph? \$\endgroup\$
    – Leaky Nun
    Commented May 19, 2016 at 9:41

1 Answer 1


37 bytes * 1403 steps = 51911 bytesteps

34 bytes * 1036 steps = 35224 bytesteps

37 bytes * 666 steps = 24642 bytesteps

(?<!\S)(?!.{21})\S+(( | - )\S+){0,2}$

Verify it here!

  • \$\begingroup\$ I think the challenge is explicitly asking for just a regex, not a solution in any other programming language. So a) you can omit the !`, but b) you'll have to make sure in works in PCRE so that it can be scored on regex101. \$\endgroup\$ Commented May 19, 2016 at 9:46
  • \$\begingroup\$ I don't think you need the 1 in {1,3}, neither in {1,20} \$\endgroup\$
    – Bálint
    Commented May 19, 2016 at 9:46
  • \$\begingroup\$ @Bálint He does, otherwise it matches exactly 3 words or 20 characters. (And if you mean {,20} that only works in Ruby and some other flavours, but definitely not .NET.) \$\endgroup\$ Commented May 19, 2016 at 9:58
  • \$\begingroup\$ @MartinBüttner is right I'm afraid, unless you can provide means to calculate an equivalent to regex101's step counting in order to obtain a score in bytesteps. Sorry for the confusion - maybe I should ask a second question that is pure code-golf without the regex-bytesteps, but it would be otherwise identical, so I don't know if that is acceptable \$\endgroup\$ Commented May 19, 2016 at 10:00
  • 1
    \$\begingroup\$ @Bálint Yeah that won't work for less then 3 words and 20 characters then. Also Kenny, I don't think your use of \b works when the match would start with something other than a word character. \$\endgroup\$ Commented May 19, 2016 at 10:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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