2010-09-07 2 views
0

В настоящее время я пытаюсь обработать файл csv на PHP с помощью preg_match(). Пример данных, которые я пытаюсь обработать, приведен ниже;PHP preg_match() Неизвестная ошибка

"SN120187", "Aldersr Rd Nr Магазины", "", "STHPTN", "50 56.4241N", "1 25.7587W", "1001077307", "2010-05-30 15:29: 49" , "10", "", "SURRSHLT3x32", "BSU243L1", "iiipiiipiiipiiipiii",

"HA035028", "Hursley Road - Leigh House Hospital", "", "Херсли", "50 59.6772N »,« 1 23.4412W »,« »,« »,« 24 »,« »,« »,« »,« Быстрая коричневая лиса перепрыгнула через ленивую собаку. Быстрая коричневая лиса перепрыгнула через ленивую собаку »,

У меня есть регулярное выражение, которое я пытаюсь использовать по этим данным (см. Ниже);

if(preg_match('/^"(?P<code>.+)","(?P<description>.+)","(?P<bay>.*)","(?P<area>.+)","(?P<lat>.+)","(?P<lon>.+)","(?P<build>.*)","(?P<msgTime>.*)","(?P<routes>.*)","(?P<simNo>.*)","(?P<displayType>.*)","(?P<version>.*)","(?P<comments>.*)",$/', $line, $matches)){} 

Регулярное выражение работает на 95% данных, однако, данные, не работает, имеет последнее поле в CSV строке, не пусто.

Я начал обдумывать данные (в основном последнее поле) и обнаружил, что следующие данные не будут проходить через регулярное выражение;

"SN120187", "Aldersr Rd Nr Магазины", "", "STHPTN", "50 54.5512N", "1 22.9273W", "1001077307", "2010-05-30 15:29: 49" , "10", "", "SURRSHLT3x32", "BSU243L1", "iiiipiiiipiiiipiiii",

"HA035028", "Hursley Road - Leigh House Hospital", "", "Херсли", "52 58.3498N », "1 26.5421W", "", "", "24", "", "", "", "iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii",

Однако, если удалить один символ из последнего поля от выше данных, он пройдет. Из игры с ним я обнаружил, что для получения этой ошибки нет согласованного шаблона; верхняя длина строки не имеет значения (это показано добавлением дополнительных символов в другие поля), а также длина конечного поля тоже не имеет значения.

Я понятия не имею, что происходит. У кого-нибудь есть идеи?

В настоящее время я использую PHP версию 5.3.2, и никаких сообщений об ошибках не появляется.

+0

просто из любопытства, почему бы вам не использовать разделение на эти данные? – ennuikiller

ответ

0

Я пробовал его локально, и он был таким же, как вы описали, у меня есть PHP 5.2.10-2ubuntu6.

Сначала попробуйте, я удалил "(?P<comments>.*)", вашего шаблона:

$line='"HA035028","Hursley Road - Leigh House Hospital","","HURSLEY","52 58.3498N","1 26.5421W","","","24","","","","iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii",'; 

$r=preg_match('/^"(?P<code>.+)","(?P<description>.+)","(?P<bay>.*)","(?P<area>.+)","(?P<lat>.+)","(?P<lon>.+)","(?P<build>.*)","(?P<msgTime>.*)","(?P<routes>.*)","(?P<simNo>.*)","(?P<displayType>.*)","(?P<version>.*)",$/', $line, $matches); 

var_dump($r, $matches); 

Выход:

int(1) 
array(25) { 
    [0]=> 
    string(169) ""HA035028","Hursley Road - Leigh House Hospital","","HURSLEY","52 58.3498N","1 26.5421W","","","24","","","","iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii"," 
    ["code"]=> 
    string(8) "HA035028" 
    [1]=> 
    string(8) "HA035028" 
    ["description"]=> 
    string(35) "Hursley Road - Leigh House Hospital" 
    [2]=> 
    string(35) "Hursley Road - Leigh House Hospital" 
    ["bay"]=> 
    string(0) "" 
    [3]=> 
    string(0) "" 
    ["area"]=> 
    string(7) "HURSLEY" 
    [4]=> 
    string(7) "HURSLEY" 
    ["lat"]=> 
    string(11) "52 58.3498N" 
    [5]=> 
    string(11) "52 58.3498N" 
    ["lon"]=> 
    string(13) "1 26.5421W","" 
    [6]=> 
    string(13) "1 26.5421W","" 
    ["build"]=> 
    string(0) "" 
    [7]=> 
    string(0) "" 
    ["msgTime"]=> 
    string(2) "24" 
    [8]=> 
    string(2) "24" 
    ["routes"]=> 
    string(0) "" 
    [9]=> 
    string(0) "" 
    ["simNo"]=> 
    string(0) "" 
    [10]=> 
    string(0) "" 
    ["displayType"]=> 
    string(0) "" 
    [11]=> 
    string(0) "" 
    ["version"]=> 
    string(57) "iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii" 
    [12]=> 
    string(57) "iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii" 
} 

Обратите внимание, что <version> теперь соответствует последним полем, в то время как <lon> соответствует два поля


Second Try; Я заменил все . возникновения с [^"]:

$line='"HA035028","Hursley Road - Leigh House Hospital","","HURSLEY","52 58.3498N","1 26.5421W","","","24","","","","iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii",'; 

$r=preg_match('/^"(?P<code>[^"]+)","(?P<description>[^"]+)","(?P<bay>[^"]*)","(?P<area>[^"]+)","(?P<lat>[^"]+)","(?P<lon>[^"]+)","(?P<build>[^"]*)","(?P<msgTime>[^"]*)","(?P<routes>[^"]*)","(?P<simNo>[^"]*)","(?P<displayType>[^"]*)","(?P<version>[^"]*)","(?P<comments>[^"]*)",$/', $line, $matches); 

Выход:

int(1) 
array(27) { 
    [0]=> 
    string(169) ""HA035028","Hursley Road - Leigh House Hospital","","HURSLEY","52 58.3498N","1 26.5421W","","","24","","","","iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii"," 
    ["code"]=> 
    string(8) "HA035028" 
    [1]=> 
    string(8) "HA035028" 
    ["description"]=> 
    string(35) "Hursley Road - Leigh House Hospital" 
    [2]=> 
    string(35) "Hursley Road - Leigh House Hospital" 
    ["bay"]=> 
    string(0) "" 
    [3]=> 
    string(0) "" 
    ["area"]=> 
    string(7) "HURSLEY" 
    [4]=> 
    string(7) "HURSLEY" 
    ["lat"]=> 
    string(11) "52 58.3498N" 
    [5]=> 
    string(11) "52 58.3498N" 
    ["lon"]=> 
    string(10) "1 26.5421W" 
    [6]=> 
    string(10) "1 26.5421W" 
    ["build"]=> 
    string(0) "" 
    [7]=> 
    string(0) "" 
    ["msgTime"]=> 
    string(0) "" 
    [8]=> 
    string(0) "" 
    ["routes"]=> 
    string(2) "24" 
    [9]=> 
    string(2) "24" 
    ["simNo"]=> 
    string(0) "" 
    [10]=> 
    string(0) "" 
    ["displayType"]=> 
    string(0) "" 
    [11]=> 
    string(0) "" 
    ["version"]=> 
    string(0) "" 
    [12]=> 
    string(0) "" 
    ["comments"]=> 
    string(57) "iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii" 
    [13]=> 
    string(57) "iiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipiiiipii" 
} 
+0

Brilliant - вторая попытка хорошо работает благодаря :) Хотя я все еще немного смущен, почему он принимает некоторые версии данных , а не другие с исходным регулярным выражением – Mabbage

2

Если это CSV-данные, используйте функцию обработки CSV, например str_getcsv, для строк или fgetcsv для чтения из файла.

+0

У меня возникли проблемы с str_getcsv(), но я более смущен тем, почему выше не работает. Я знаю, что могу делать CSV-файлы другими способами, но я действительно озадачен этой проблемой регулярного выражения. – Mabbage

0

[^"] ответа хорошо, но я думаю, что вы могли бы также включить все + и * операторов на ленивые оператор, сделав их +? и *? соответственно.

preg_match('/^"(?P<code>.+?)","(?P<description>.+?)","(?P<bay>.*?)","(?P<area>.+?)","(?P<lat>.+?)","(?P<lon>.+?)","(?P<build>.*?)","(?P<msgTime>.*?)","(?P<routes>.*?)","(?P<simNo>.*?)","(?P<displayType>.*?)","(?P<version>.*?)","(?P<comments>.*?)",$/', $line, $matches); 

Кажется, что одно из выражений хватало слишком много линии. Я не совсем уверен, почему (но это приведет к большому оттоку).

+0

'[^"] '- это гораздо лучшее решение.'. *? 'будет * try * принимать кратчайшее совпадение, но оно все равно может совпадать, если либо регулярное выражение, либо данные неверно. Это не произойдет с '[^"] * ', потому что он не может пройти мимо заключительной цитаты. Фактически, вы можете даже использовать * ownerive * quantifier ('[^"] * + ') и получать повышение производительности в качестве бонуса. –

Смежные вопросы