2013-12-04 2 views
0

Я собираюсь опубликовать упрощенную версию моей проблемы, поэтому, пожалуйста, дайте мне знать, если вы хотите получить более подробную информацию.Объедините меняющееся количество строк с помощью regex

У меня есть текстовый текстовый файл, содержащий текст, похожий на файл журнала. Он содержит то, что должно быть 541 строка, начинающаяся с 9-значного числа и сопровождаемая различными битами данных. Некоторые из этих данных представляют собой XML, большая часть которых содержит дополнительные новые символы линий, которые заставляют эти строки разделяться и теперь имеют файл в ~ 30k строк. Я хочу объединить этот файл обратно до 541 строки, по существу, консолидируя любые строки, которые не начинаются с 9-значного числа на предыдущей строке.

Прежде всего, 9-значные цифры начинаются с '11', поэтому я запустил совпадение на 11\d{7} и получил ровно мои 541 совпадения (т. Е. В моем файле не совпадают номера, которые могут совпадать неправильно). Я также смог сопоставить все строки, которые не начинаются с этого номера, с ^(?!11\d{7})(.|\n)*$. Я хотел бы объединить все эти строки вместе, а также придерживаться этого на линии раньше (это линия, которая начинается с 11 \ d {7}). Мои поисковые запросы в Интернете только нашли решения с конечным и/или согласованным числом строк для конкатенации, но этот XML зависит от длины и структуры. Наконец, в этом файле есть XML, который не является, разделенным по строкам, поэтому сопоставление и объединение всех XML без разбора также не является вариантом. Предложения приветствуются. Вот пример, чтобы проиллюстрировать то, что я пытаюсь сделать:

До:

117337909,some text,42930842,misc data,<xmlRoot> 
<parent1> 
<foo>data</foo> 
<bar>123</bar> 
</parent1> 
</xmlRoot> 
116425348,some more text,2df34as,blah,<xmlRoot> 
<parent2> 
<foo>data</foo> 
<bar>123</bar> 
</parent2> 
</xmlRoot> 

После:

117337909,some text,42930842,misc data,<xmlRoot><parent1><foo>data</foo><bar>123</bar></parent1></xmlRoot> 
116425348,some more text,2df34as,blah,<xmlRoot><parent2><foo>data</foo><bar>123</bar></parent2></xmlRoot> 
+1

Что вы используете регулярное выражение в (языке и/или приложении)? – Joe

+0

Почему бы не заменить каждый символ ввода перед элементом? –

+0

@Joe - я использую Notepad ++ или Sublime Text 2 – ggrigery

ответ

3

Вы можете использовать это:

String result = yourstring.replaceAll("\\r?\\n(?!11\\d{7}(?!\\d))", ""); 

Узор детали:

\\r?   # optional carriage return (for windows format) 
\\n   # line feed 
(?!   # open a negative lookahead (ie: not followed by) 
    11\\d{7} # 11, seven digits 
    (?!\\d) # not followed by another digit (to ensure that there isn't more 
       # digits after, "1123456789" will not match) 
)    # close the lookahead 
+0

Хорошая точка на \ r. Я удивлен, что не существует метаданных, содержащих метасимволы. – Joe

+0

@ Joe: действительно, я не думаю, что есть эквивалент Perl/PCRE '\ R' в Java. –

+0

Это сработало отлично, спасибо. Можете ли вы сломать его компоненты, чтобы я мог понять, что происходит? – ggrigery

0

Просто поиск этого регулярного выражения:

(?s)[\r\n]*(?!11\d{7}) 

и заменить пустой строкой, т.е. "".

0

В Notepad ++ вы можете, вероятно, сделать это с помощью расширенного поиска. Введите текст внутри кавычек, а не кавычки.

  1. Поиск: "\r\n" Заменить: " " [пробел]
  2. Поиск: " (11\d\d\d\d\d\d\d)" Заменить: "\n\1"

Это не будет работать, если у вас есть другие 9-значные номера, начинающиеся с 11, но если вы не это может быть проще, чем делать это в регулярном выражении. Notepad ++ не очень хорош в регулярных выражениях, охватывающих новые строки из того, что я читал.

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