Сложный Preg_Match - соответствие 500 символов после нахождения ключевого слова, но не запускается до следующего разрыва строки

Сначала, чтобы объяснить, что я новичок в php, и я очень новичок в preg_match и нахожу это запутанным, я пытаюсь найти ключевое слово: exception:, а затем, начиная со следующей строки, вытащите 300 символов

У меня уже есть предварительное совпадение для этого, но я хочу его улучшить, я извлекаю 300 символов из ключевого слова, но проблема в том, что ключевое слово - это имя исключения, а затем в следующей строке - ошибка кода, исключение может быть написан на любом количестве языков, но ошибка кода после исключения не зависит от языка, поэтому я хочу отфильтровать исключение, поскольку оно зависит от языка, поэтому я знаю, соответствует ли исключение 100% при последующем сравнении.

Вот несколько примеров исключения:

Exception: System.Runtime.InteropServices.COMException (0x800401D0): OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Windows.Clipboa

exception: Specified cast is not valid.
Query:Select * from TourneyData where Player_id = 1412
14:14:18.868 [SetCurrentPlayer:12 - DatabaseBase.HandleDatabaseConnectionException] 4: System.InvalidCastException: Specified cast is not valid.
at NpgsqlTypes.NpgsqlTimeStamp.op_I

Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Windows.Forms.Application.ThreadContext.ExitCommon(Boolean disposing)
at System.Windows.Forms.Application.ExitInternal()
at System.Windows.Forms.Application.Exit(C

Итак, как я планирую добраться до ошибки кода, так это отобразить всю информацию в следующей строке, следующей за исключением ключевого слова:

В последнем примере я хотел бы получить следующий результат:

at System.Windows.Forms.Application.ThreadContext.ExitCommon(Boolean disposing)
at System.Windows.Forms.Application.ExitInternal()
at System.Windows.Forms.Application.Exit(C

Хорошо, вот код, который я уже использую для сбора 300 символов после ключевого слова:

// Snippet length constant
define(SNIPPET_LENGTH, 300);

$pos = stripos($body,$keyword);   
$snippet_pre = substr($body, $pos, SNIPPET_LENGTH);

Теперь я также использую preg_match в нескольких функциях для извлечения информации, например, в коде есть эта информация журнала поиска:

12:19:42.787 [Main:1 - Bootstrapper.LogSystemInfo] Current culture: it-IT
12:19:42.865 [Main:1 - Bootstrapper.LogSystemInfo] Operating System Name: Microsoft Windows 7 Home Premium 
12:19:42.865 [Main:1 - Bootstrapper.LogSystemInfo] Operating System Architecture: 64 bit
12:19:42.865 [Main:1 - Bootstrapper.LogSystemInfo] Operating System Service Pack: Service Pack 1

Это preg_match, только в том числе, поскольку он может помочь различить, как различаются разрывы строк, потому что он улавливает всю информацию из ДО разрыва строки, но я не могу понять, как получить 300 символов ПОСЛЕ разрыва строки:

    preg_match('/Current culture: (.*)/', $body, $culture_pre);
preg_match('/Operating System Name: (.*)/', $body, $os_name_pre);
preg_match('/Operating System Architecture: (.*)/', $body, $os_bit_pre);
preg_match('/Operating System Service Pack: (.*)/', $body, $os_service_pack_pre);

Сообщите мне, если вам понадобится дополнительная информация


person user1547410    schedule 31.12.2012    source источник


Ответы (1)


preg-match и все регулярные выражения в целом трудно справиться, когда они сталкиваются с \n или \r\n.

Вы можете использовать модификатор m для решения некоторых случаев, но единственное, что он делает, это изменяет поведение зарезервированных символов $ и ^, заставляя их соответствовать концу или началу строки с учетом \n, поскольку это разделит строку на разные подстроки . Не думаю, что это сработает в вашей проблеме, но вы можете попробовать.

Есть и другие возможные способы исправить это, хотя не все из них абсолютно чистые:

1- простой способ: удалите \r\n или \r перед применением регулярного выражения:

$chars=array("\r\n", "\n", "\r");
$string=str_replace($chars, '', $string);

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

2- простой и не очень чистый способ: измените \n на специальный символ, который, как вы знаете, он не появится в строке (например, #), примените регулярное выражение, снова измените специальный символ на \n. Это некрасиво, но если у вас мало времени, это работает.

3 - не такой простой, чистый способ: разделите строку, используя \n в качестве ключа, прочтите ее построчно, применяя preg_match(), если она совпадает, сохраните следующие 2 или 3 (или любое другое число, которое вам нужно сохранить).

person Naryl    schedule 31.12.2012
comment
Мне показалось, что это отлично сработало // Убираем первую строку $ pos1 = stripos ($ snippet, '‹br /›'); $ snippet_new = substr ($ snippet, $ pos1, 500); echo $ snippet_new2; - person user1547410; 01.01.2013