Gordon
Gordon

Reputation: 6873

StartsWith in a switch

I am trying to parse some Autodesk Revit journal files, which have both comment lines that start with an apostrophe, and command lines that don't. The comment lines can further start with 'E or 'H or 'C to signify a time stamp which I need to work with as well. So I figured that my logic would be:

If Comment
  Switch TimeStampType
Else
  Command

I found this, and I figured if switch ($someString.ToLower()) works, then switch ($line.StartsWith()) would too (I know, that's a bit of a reach, as ToLower and StartsWith are completely different concepts).

However, this is throwing Cannot find an overload for "StartsWith" and the argument count: "0". at if ($line.StartsWith("'")). But that's a bit of a misdirect because if I REM the entire switch it throws no errors, so the error must be in the switch.

        if ($line.StartsWith("'")) {
            switch ($line.StartsWith()) {
                "'E " {
                    # handle Timestamp
                }
                "'H " {
                    # handle Timestamp
                }
                "'C " {
                    # handle Timestamp
                }
                Default {}
            }
        } else {
            if ($line -like "*$command*") {
                Write-Host "$line"
            }
        }

I have also tried escaping the apostrophes with `, with the same results, as well as using switch like this, as suggested in the link.

{$_ -eq "'E "} {
        # handle Timestamp
}

Again, with the same results. So finally I ended up with

    if ($line.StartsWith("'")) {
        switch ($line) {
            $_.StartsWith("'E ") {
                # handle Timestamp
            }
            $_.StartsWith("'H ") {
                # handle Timestamp
            }
            $_.StartsWith("'C ") {
                # handle Timestamp
            }
            Default {}
        }
    } else {
        if ($line -like "*$command*") {
            Write-Host "$line"
        }
    }

That works, but also seems perhaps inelegant. So, have I found the one or best answer, or is there a better approach here that I am missing?

Upvotes: 3

Views: 3462

Answers (2)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174690

Instead of using String.StartsWith(), you could just use a wildcard switch:

switch -wildcard ($line){
  "'E *" {
    # $line starts with 'E
  }
  "'H *" {
    # $line starts with 'H
  }
  "'C *" {
    # $line starts with 'C
  }
}

or a regex switch:

switch -regex ($line){
  "^'E " {
    # $line starts with 'E
  }
  "^'H " {
    # $line starts with 'H
  }
  "^'C " {
    # $line starts with 'C
  }
}

Be aware that if you were to use "somestring".StartsWith() as your switch input argument, the only values you would ever catch would be $true or $false, since that's what StartsWith() returns:

switch($line.StartsWith("'E")){
  $true {
    # $line starts with 'E
  }
  $false {
    # $line doesn't start with 'E 
  }
}

Upvotes: 4

Patrick Meinecke
Patrick Meinecke

Reputation: 4173

You could also use the Substring method.

switch ($line.Substring(0,3)) {
    "'E " {
        # handle Timestamp
    }
    "'H " {
        # handle Timestamp
    }
    "'C " {
        # handle Timestamp
    }
    Default {}
}

Upvotes: 1

Related Questions