in reply to more elegant way to parse this?

If you really want to split into records with a regex:

/^(BSS.*?)(?=^BSS|\z)/smg

But I don't know why you want the records at all. This format seems easiest to parse line-by-line.

my @essids; for (qx| sudo iw dev wlan0 scan |) { /^\s*SSID:\s*(.*)/ and push @essids, $1; }

If you need other information besides the ssid, maybe you can just do something like this:

my @records; for (qx| sudo iw dev wlan0 scan |) { if (/^BSS\s*(.*)/) { push @records, { BSS=>$1 } } elsif (/^\s*(\w+):\s*(.*)/) { $records[-1]{$1} = $2 if @records } } foreach my $record (@records) { print "$record->{SSID}\n"; }