Я написал регулярное выражение, которое протестировал на сайте rubular.com, и оно вернуло 4 совпадения. Тему тестирования можно найти здесь http://pastebin.com/49ERrzJN, а PHP-код приведен ниже. По какой-то причине код PHP возвращает только первые 2 совпадения. Как сделать так, чтобы совпадали все 4? Кажется, это как-то связано с жадностью или около того.
$file = file_get_contents('x.txt');
preg_match_all('~[0-9]+\s+(((?!\d{7,}).){2,20})\s{2,30}(((?!\d{7,}).){2,30})\s+([0-9]+)-([0-9]+)-([0-9]+)\s+(F|M)\s+(.{3,25})\s+(((?!\d{7,}).){2,50})~', $file, $m, PREG_SET_ORDER);
foreach($m as $v) echo 'S: '. $v[1]. '; N: '. $v[3]. '; D:'. $v[7]. '<br>';