2007-01-29

What do the anchors ^ and $ mean in a regular expression?

One of the least great things about regular expressions is that there's no One True Standard. Sure, there's POSIX, but it's both broken and limited, so no-one really happily uses that. There's Perl, too, and in fact most modern regular expression implementations imitate Perl reasonably well. There's often trouble with things like Perl's embedded code syntax, but that's fair enough: you can't realistically expect every regular expression library to include a Perl interpreter, and most people wouldn't want such a thing even if it were available.

Java's documentation for java.util.regex.Pattern even contains a "Comparison to Perl 5" section, but it's sadly incomplete. It doesn't mention minor bugs such as the treatment of # in a character class (despite it being a long-standing bug and there being no obvious intention of actually fixing it).

Usually, though, it's fairly esoteric stuff that differs between implementations. The basics are the same everywhere. Or so I'd have said yesterday. In particular, I thought "what do the anchors ^ and $ mean in a regular expression?" was a particularly easy question; one that even a regular expression beginner could answer completely.

So. What do the anchors ^ and $ mean?

Let's start with Perl. You'll have to forgive my dialect; I left long ago and have rarely ventured back since (and, as it turns out, my first attempt was wrong and had to be corrected by Chris Reece). If we give Perl a string with a bunch of newlines and ask it how many times $ matches, we get the perfectly sensible answer "once":

$ perl -e '@m = "a\nb\nc\nhello\nworld\n" =~ m/$/g; print scalar(@m)."\n";'
1

By default, $ matches end-of-input, and there's only one end of input.

If we give Perl the same string and ask it how many times $ matches in multiline mode, we get this answer:

$ perl -e '@m = "a\nb\nc\nhello\nworld\n" =~ m/$/mg; print scalar(@m)."\n";'
6

To me, this doesn't match the documentation. perlre(1) says:

m Treat string as multiple lines. That is, change "^" and "$" from
matching the start or end of the string to matching the start or
end of any line anywhere within the string.

Seemingly, that should be "...to also matching the end of any line anywhere within the string".

Moving on to Ruby, we see the same result. There isn't, as far as I know, any canonical documentation for Ruby's regular expression syntax, but the on-line "pickaxe" book says that "$ Matches the end of a line". So, for some reason, Ruby thinks our string has a newline we can't see.

$ ruby -e 'puts("a\nb\nc\nhello\nworld\n".scan(/$/).length())'
6

We can start up irb(1) and see just how convinced it is:

irb(main):001:0> "a\nb\nc\nhello\nworld\n".scan(/$/)
=> ["", "", "", "", "", ""]

Even more curious is that multiline mode seems to make no difference:

irb(main):002:0> "a\nb\nc\nhello\nworld\n".scan(/$/m)
=> ["", "", "", "", "", ""]

Turning to the documentation, we find out why. The definition of multiline mode is given as "Normally, '.' matches any character except a newline. With the /m option, '.' matches any character". So it turns out that in the land of the rising sun, multiline mode means something completely different. Java and Python call this dotall mode, while Perl calls it single-line mode. Everyone but Ruby uses (?s) to control this (after Perl's "single-line" name).

(If you want start-of-input or end-of-input anchors in Ruby, you need to use \A or \z, which are also available in Java, Perl, and Python. You don't want \Z because \z behaves in the same way as $; in Java, it's even implemented using the same underlying primitive.)

And so to Java:

import java.util.regex.*;

public class test {
public static void main(String[] args) {
Pattern p = Pattern.compile("$");
Matcher m = p.matcher("a\nb\nc\nhello\nworld\n");
int count = 0;
while (m.find()) {
++count;
}
System.err.println(count);
}
}

How often does Java claim that $ matches in our now-familiar string?

2

And in multiline mode?

6

Taking the latter result first, although idiotic, this appears to be the documented behavior: "In multiline mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the input sequence". Note well that "or" (emphasis mine). This seems to be Python's interpretation of $ in multiline mode also, so that's a full house. I don't know why anyone would want this behavior, but my guess is that they felt that there's an implicit line terminator at end of file (but even if there's an explicit line terminator?).

As for the former result, presumably that's a Java bug? Here's a slight variant that shows where the matches occur:

import java.util.regex.*;

public class test {
public static void main(String[] args) {
Pattern p = Pattern.compile("$");
Matcher m = p.matcher("a\nb\nc\nhello\nworld\n");
while (m.find()) {
System.err.println(m.start() + ".." + m.end());
}
}
}

And here's the output:

17..17
18..18

So we're getting a match on the final line terminator and then another match on end-of-input. If the input doesn't end in an explicit line terminator, Java correctly reports just one match.

I can't find anything in the Java documentation to suggest the two-match behavior isn't a bug, and have filed a bug report already. In the meantime, you might like to try \z if you really just want to match at the end of input.

2007-01-17

Review: Cooler Master Stacker 830 / Cooler Master iTower 930

If you read ars technica's system guides, you'll have heard of the Cooler Master Stacker, even if you've never seen the case. It's been their "God Box" case recommendation for a while. I bought one recently because my girlfriend kept complaining that the Ultra 20 was too ugly. The all black CM Stacker seemed like a good choice for case-buying neophytes because we both thought it looked pretty good, it was large enough that we knew we'd have no trouble fitting anything, it was nice and sturdy, and felt very well-made.

The slide-out motherboard tray is quite convenient. The Stacker's a spacious case anyway, but being able to pull out the tray gives you even more room. The huge amount of space made cable management a bit more difficult, I felt. I'm not entirely sure why.

The fact that the front door covers all the drive bays means that when I eject an optical drive, it comes out half a centimeter, bangs against the door, and goes back in again. I blush, open the door, and eject again. I have yet to learn this. I swore to myself I'd not buy another case where the front door covers the optical drive bay.

The Stacker has lots of holes. Both side panels are mesh, the front door is mostly mesh, and there's a strange hold on the top that's mesh (through which you can see the unpainted metal interior on an otherwise black case). All this means there's plenty of noise. The already noisy nVidia GeForce 7600GT became unbearable (but that's a subject for another post), and even Sun's power supply came under scrutiny (but that's a subject for yet another post). Expect to start spending money to reduce noise if you're at all sensitive to it and buy a Stacker.

The side panels suck. There are handy levers on the back to lock or unlock the side panels, but the panels themselves aren't designed to fit in one obvious manner. To be honest, I've not had this much trouble scraping bits of metal against other bits of metal in years. (I think the last time was when a top of the range Dell Optiplex had a 66 MHz processor and a metal case, though that case was a dream compared to some of its contemporaries. Or a nightmare of bloody hands, should you ignore the "this is not a handle" stamped into a convenient-looking metal bar inside the case.) I'd love to see more cases like Apple's older PowerMacs, where there was just a little release and then the side would swing down but stay attached. Even the recent PowerMac G5 and the Mac Pro is fine, though. No scratching, no scraping, no guessing, no banging. There's one way to fit it, it's obvious what that way is, and it's well-enough made that it fits beautifully.

I'm sure if you have the knack or better lighting or whatever, the Stacker's fine, but I really shouldn't have to go out of my way. Easily removable case side panels is not a hard problem.

The worst thing about the Stacker, though, is how hard it is to add/replace disks. You have to unlock both side panels, remove both side panels, disconnect the cage fan from the motherboard fan header, open the front door, open two front panels, pop out the drive bay blanking plates, unscrew the drive cage, slide it out, unscrew the drive, slide in the new drive, fight to line up the drive (because there are no rails in the cage), screw in the new drive, slide in the drive cage, fight to line it up (because there are no rails for the cage), screw in the cage, pop back the blanking plates, shut the front panels, shut the front door, replace the side panels, lock the side panels in place.

It's all too easy in all that to forget to disconnect the cage fan from the motherboard fan header. With non-hilarious consequences.

Speaking of fans, the supplied rear fan uses a molex connector for power, requiring a converter to power it from a motherboard fan header, or a cable management problem and the waste of a power supply connector.

To end on a positive note, the way the power supply is fitted is great. I appreciated this immediately, and appreciated it even more after playing with a different Cooler Master case. There are long rails to hold the power supply in place, and plenty of space all around. It slides in nicely, and they defy you to find one that's too big to fit. There's no extraneous metalwork to get in the way of fan holes, either.

The Stacker is a well-made case. It's just not a very well-designed case. There are several places where the design lets it down. It's not at the standard of Apple's "pro" cases, it's not at the standard of the Sun case I started with, and it's not at the standard of the other Cooler Master case I've played with recently...

CM Stacker 830

Good:


  • Loads of room.

  • Slide-out motherboard tray.

  • Solidly built.


Bad:


  • Slide-off sides annoyingly difficult to use.

  • Swapping drives takes a lot of work.

  • There's a big hole in the top for reasons that escape me.

  • Rear fan has a molex connector rather than a fan header connector.

  • More airflow means more noise.



More recently, we bought a CM iTower 930. Ignore the terrible name for a moment. I know it sounds like a USD20 piece of plastic, but it's actually a really nice case. The killer feature for me was the hot-swappable SATA trays on the front. I reckon that if one thing should be easy with a computer, it should be adding RAM (unless the computer's a server, or you fit as much RAM as it can address when you buy it). But after that, the next most important thing to be easy is adding/replacing disks. Apple's "pro" cases have been strong in this regard. My dual G5 still stands out, with its two internal SATA trays and the spare screws screwed into nearby holes in the internal metalwork, and the little plastic hinge to lock them in place. The newer Mac Pro is even nicer. Sadly, I've yet to see anything like that in the PC world, and it's not like I can trivially gut the PowerMac G5 case and fit an ATX power supply and motherboard.

So, yeah, looking for my second case I had two things in mind:

1. I wanted at a minimum perpendicular drive bays, so I wouldn't have to take the front and side off, and remove and unscrew a bunch of stuff just to add/replace a disk, like I do with the Stacker. It's not like I do this every day, but still, it really is far more of a pain than it ought to be.

2. I wanted either no front door, or a front door that didn't cover the optical drive bay.

I almost bought a CM Centurion 534. (Coincidentally, this is a close relative of ars' current "Hot Rod" case recommendation. I swear I wouldn't jump off a bridge if they told me to!) The case was on special offer at my local branch of Central Computer (and it's an inexpensive case anyway, and even comes with a power supply), but they'd sold out of the color I wanted, and in the meantime I'd seen the iTower 930.

The big selling point of this case is the hot-swappable SATA trays on the front. Yes, they're partly a gimmick, at least as far as home users are concerned: I don't think many home users really need to swap disks all that often. I'd rather have had them on the inside, like in Apple's Mac Pro, but if they don't make it, I can't buy it.

There's a lot less room inside the iTower than the Stacker, and there's a remarkable amount of stuff in the way. There's the SATA board behind the drives, with a fan behind it, so watch out if you have a crazy-large graphics card, though there's plenty of room for low-end and mid-range cards. There's also a strange assembly that serves both as a BTX-style funnel for the CPU fan and as a support for the graphics card, which might be handy if you've replaced your card's noisy stock fan with something quieter.

Speaking of cards, this case uses little plastic clips to lock PCI cards in place. Personally, I prefer the usual screws, even if they do require a screwdriver. The clips are fine, though, once you get used to them.

The supplied rear fan uses a motherboard fan header connector, but comes with a converter should you need molex. The SATA board also provides extra fan headers, which could potentially be helpful, though I had no use for them myself.

For some reason, I found cable management really easy in this case. I think it was because there was relatively little empty space, so it was always easy to tuck a cable away. The use of a modular power supply helped too, because the unneeded cables stayed in the box rather than needing to be hidden anywhere. I don't ever want to have to change the power supply, though. It was a real job getting it into its special compartment. It needs to be slid in from behind, but it's too tight a fit to really slide, so I did what any man would do in the situation and kneeled behind the case, groin level with the PSU, and thrust it in using my hips.

Much to the amusement of my other half. "Did I just see you hump that computer?"

The other thing I didn't like about the PSU compartment is that the cut-out on the bottom for the fan isn't very large. So if your PSU has a big bottom fan, some of it will be obscured.

On the subject of tight fits, note that you'll have to do some (tool-free) disassembly to get at anything. The CPU funnel/card support needs to come out, and to get a motherboard in or out you'll want to pay attention to the manual's suggestion that you take the fan off the SATA board. If you have a micro-ATX board, you'll not be very amused when you find that one of the stand-off holes is missing (the bottom-right one), or at least it was in my case. (All the ATX stand-offs were present.)

CM iTower 930

Good:


  • 4 hot-swappable SATA trays.

  • Slide-off side works well.

  • Almost screwless.

  • Solidly built.

  • Rear fan has a fan header connector.


Bad:


  • Power supply space very tight.

  • Side panel's thumbscrews aren't spring-attached to panel.

  • Missing micro-ATX stand-off hole.



All of the Cooler Master cases I've come across feel great, and for some reason many of their designs appeal aesthetically. Their manuals are pretty good, in the pictorial style of IKEA and LEGO, though never achieving quite the same level of clarity.

Of these two, I'd recommend the iTower 930 over the Stacker, unless you're a casemodder.

If I seem overly harsh about the Stacker, bear in mind that it's a USD250 case. The iTower 930 seems to me to be a much better case (unless you need the extra space), for USD100 less.