Блокнот ++ Найти и заменить: подстановочный знак различное количество строк?
У меня есть каверзная проблема. Мне нужно внести небольшие изменения в большое количество XML-файлов (более 500). Изменение включает в себя переключение значения с "ложь" на "истина". Строка, которую нужно изменить, выглядит следующим образом:
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
И это должно стать:
<SizeIsMeasuredLineLine>true</SizeIsMeasuredLineLine>
К сожалению, в каждом файле есть множество экземпляров этого набора тегов, поэтому мы не можем просто найти и заменить. То, что делает этот набор тегов уникальным, состоит в том, что они идут через несколько строк после:
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
Однако каждый файл имеет свое имя элемента, поэтому я использовал шаблоны для их фильтрации.
<CID>.*BUS..*.DKV</CID>
Проблема в том, что количество строк между частью CID и строкой, которую нужно изменить, не согласовано от файла к файлу. Мне нужно найти способ подстановки строк между ними и заменить строку размера.
Есть идеи? Я уже попробовал:
<CID>.*BUS..*.DKV</CID>.*?<SizeIsMeasuredLineLine>true</SizeIsMeasuredLineLine>
Но почему-то это не сработало. Заранее спасибо!
Изменить в ответ на комментарий:
По сути, я говорю, что код выглядит так:
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
И другие разделы в коде выглядят так:
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
в других местах в коде. Поэтому я использую строку CID .BUS .DKV в качестве отправной точки. По сути, мне нужно изменить первое вхождение строки SizeisMeasured, которая идет непосредственно ПОСЛЕ строки CID .BUS .DKV. Но между ними есть много других строк (ни одна из которых не является последовательной от файла к файлу), которые меня не волнуют, и они запутывают мой поиск.
2 ответа
Вы можете использовать отрицательный взгляд, как это. Поиск
(?!<CID>.*BUS..*.DKV</CID>(.*?))<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
и заменить на
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
Регулярное выражение, соответствие. новая линия
Негативный Lookahead (?!a)
и отрицательный взгляд сзади (?<!a)
Также называются Lookaround. Lookaround сопоставляет символы, но затем бросает совпадение, возвращая только результат: совпадение или отсутствие совпадения.
Вы можете найти больше здесь Lookahead и Lookbehind Утверждения нулевой длины
Синтаксический анализ XML при соблюдении иерархии с помощью регулярных выражений неоправданно затруднен. Я бы использовал совершенно другой инструмент, специально предназначенный для того, что вы пытаетесь сделать, - преобразование XML. Я говорю о XSLT. Итак, вот мое решение вашей проблемы с использованием XSLT. Существует целый ряд веб-сайтов, которые вы можете использовать для преобразования вашего XML с помощью XSLT или же вы можете запустить XSLT локально.
Проблема была бы проще, если бы каждая из ваших групп (CID, а затем SizeIsMeasuredLineLine) находилась в пределах одного родителя, но код ниже просматривает первого предшествующего брата CID, чтобы увидеть, какое значение он имеет. Если оно имеет значение, совпадающее с регулярным выражением (ITEMNAME.[^.]+.ITEMNAME..+), тогда оно заменяет false на true. Все остальные элементы просто копируются на выход.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SizeIsMeasuredLineLine[matches(preceding-sibling::CID[1], 'ITEMNAME\.[^.]+\.ITEMNAME\..+')]">
<xsl:copy>TRUE</xsl:copy>
</xsl:template>
Вот образец XML, который я создал, чтобы проверить выше:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<CID>ITEMNAME.BUS.ITEMNAME.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.122.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.44.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.BUS.33.DKV</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
<CID>ITEMNAME.COLR.ITEMNAME.FCLR</CID>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<tag>Some Number of Other lines</tag>
<SizeIsMeasuredLineLine>false</SizeIsMeasuredLineLine>
</parent>