Parsing Text as ASCII in Swift

This had me scratching my head for awhile. I wrote a routine to convert strings like “F#3” to its corresponding MIDI note number (54, if my routine is correct). First of all, there’s a way of evaluating the text with a regular expression. In my case I used the following (not quite complete, but close enough) (‘key’ is the string we’re trying to parse):

	let expression = "^[a-gA-G][b|#]?[0-8]$"
	let regex = try! NSRegularExpression(pattern: expression, 
			options: NSRegularExpressionOptions(rawValue:0))
	
	if 0 == regex.numberOfMatchesInString(key as String, 
			options: NSMatchingOptions(rawValue: 0), 
			range: NSRange(location: 0, length: len)) {
		return nil
	}

OK, that’s well and good, but Swift strings are unicode. How to convert to ASCII and parse the individual characters?

And the answer is:

	let s = key.cStringUsingEncoding(NSASCIIStringEncoding)

This returns an intimidating UnsafePointer, which, after a bit of fumbling around, I found I could treat as an array. For instance, the first stage of parsing the first character is like so:

	var s0 = s[0]
	switch s0 {
	case 65...71:	// UC A - G
		s0 = s0 - 65
	case 97...103: // LC a - g
		s0 = s0 - 97
	default:
		return nil
	}

Using decimal numbers instead of characters in the switch statement is quite icky, but I couldn’t figure out a way to use such things as ‘A’. The compiler does not like them.

I’ll leave the rest of the routine as an exercise for the reader (although I doubt anyone else is going to care enough to bother).

Leave a Reply

Your email address will not be published. Required fields are marked *