4

I'm using Swiftlint to enforce some practices in our codebase. I want to add a custom rule that makes sure a { always appears after a newline. I thought I knew regexes, but can't seem to figure it out. I just check if a line contains any characters other than whitespace before the {. It is allowed to have stuff after the {.

What I have now:

invalid_open_brace:
    name: "Open brace should start on its own line"
    regex: "(\S+.*\{)"
    message: "Open brace should start on its own line"
    severity: warning

Here are some example strings that should and should not match:

// NO MATCH
else if let var1 = var1 as? String, !var1.isEmpty 
{

//NO MATCH
class Person
{
    // MATCH
    int() 
    {
    }

    // NO MATCH
    function() 
    {

    }
 }

// MATCH
function() {

}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Haagenti
  • 7,974
  • 5
  • 38
  • 52
  • Characters other than `\S` before `{` means you need to use `"\\s[{]"` (check if there is a whitespace before `{`). – Wiktor Stribiżew Mar 09 '17 at 07:53
  • @WiktorStribiżew Updated my question. I want to matches lines that contain a { with some else then whitespace before them. – Haagenti Mar 09 '17 at 07:58
  • Good, then use `"\\S[{]"` (or `"\\S\\{"`) (note that double ecape is necessary when used as a string literal). – Wiktor Stribiżew Mar 09 '17 at 07:59
  • @WiktorStribiżew when i type ur solution in https://regex101.com/ with content: else if let var1 = var1 as? String, !var1.isEmpty {. Nothing gets highlighted – Haagenti Mar 09 '17 at 08:00
  • Nothing will, since `\S\{` matches in `.isEmpty{`. You say you need to match only if there is anything other than whitespace before `{`. Please reconsider your requirements, and update your question. – Wiktor Stribiżew Mar 09 '17 at 08:01
  • But than my question isn't clear yet. I want to match { when they are not a newline. So the open brace should be on a newline not after isEmpty – Haagenti Mar 09 '17 at 08:03
  • Try `\\S[\r\n]+\\{` (or `\\S\\R+\\{`) to match a non-whitespace, line break chars, `{`. See [this regex demo](https://regex101.com/r/2AWyC5/1) - is that what you need to match? – Wiktor Stribiżew Mar 09 '17 at 08:05
  • https://regex101.com/r/2AWyC5/1 – Wiktor Stribiżew Mar 09 '17 at 08:05
  • @WiktorStribiżew could u check my comments in https://regex101.com/r/2AWyC5/2 – Haagenti Mar 09 '17 at 08:09
  • And what are the *requirements*? What is the difference between `!var1.isEmpty{` and `Person{`? Why shouldn't the first one match and the second should? – Wiktor Stribiżew Mar 09 '17 at 08:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/137637/discussion-between-scarecrow-and-wiktor-stribizew). – Haagenti Mar 09 '17 at 08:11

1 Answers1

4

Your (\S+.*\{) regex matches any char that is not whitespace (one or more reptitions - \S+), then any char other than linebreak (including non-whitespaces - here is the root cause of your issue), and {.

You may use

\S[ \t]+\{

See the regex demo.

Details:

  • \S - any non-whitespace char
  • [ \t]+ - one or more (+) horizontal whitesapces (can be replaced with [\t\p{Zs}]+ where \p{Zs} matches all horizontal Unicode whitespace without a tab).
  • \{ - a literal { symbol.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563