У меня есть файл, обычно файлы XML. Я хочу заменить все вхождения "xy" на "p.q". Но во время этой замены я хочу игнорировать вхождения xy в комментариях().
Я пытался использовать String.replaceAll() для выполнения этой задачи.
Например:
<?xml version="1.0" encoding="UTF-8"?>
<name>This occurrence of x.y should be replaced</name>
<!-- This occurrence of x.y should not be replaced -->
Я попытался использовать String.replaceAll("x [\.] Y", "pq"), но я мог видеть, что вхождения в комментарии также заменяются
Я мог бы использовать другую альтернативу, по которой я могу читать файл за строкой и исключать строки, начинающиеся с комментариев, но меня интересует использование replaceAll()
Укажите способ, которым это может быть достигнуто.
Хотя это не строго ответ, который вы ищете, у меня есть рекомендация.
Я бы рекомендовал использовать правильный XML-парсер, такой как Java DOM, для проверки и замены текста в ваших узлах, вместо того, чтобы иметь дело с вашим XML как сырой String
. Что-то вроде этого должно заменить соответствующий текст на вашем узле, если они не являются комментарием.
File f = new File("your.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(f);
NodeList eList = doc.getElementsByTagName("*");
for (int e = 0; e < eList.getLength(); e++) {
Node element = eList.item(e);
NodeList nList = element.getChildNodes();
for(int n = 0; n < nList.getLength(); n++){
Node node = nList.item(n);
if(node.getNodeType()==Node.TEXT_NODE){
node.setNodeValue(node.getNodeValue().replace("x.y", "p.q"));
}
}
}
Если проблема с памятью/эффективностью (например, когда ваш.xml огромен), вам лучше использовать SAX, который быстрее (немного больше кода) и не сохраняет XML в памяти.
Как только ваш Document
будет отредактирован, вы, вероятно, захотите использовать трансформатор для создания подходящего вывода. (Официальное руководство здесь, реверанс комментария Бориса Спайдера)
Надеюсь это поможет.
Дальнейшее чтение;
Document
в String
для его сохранения - это неправильно. Transformer
специально разработан для этой задачи. Здесь есть учебник .
Если вы используете регулярное выражение, опция должна использоваться для поиска заметок только для внешних комментариев:
(?s)x\.y(?!(?:(?!<!--).)+-->)
Как строка Java:
"(?s)x\\.y(?!(?:(?!<!--).)+-->)"
Использовал модификатор (?s) DOTALL
для создания .
также соответствуют новостям.
Тест в regexplanet (нажмите на Java)
1024
попробуйте это в (?m)
многострочном режиме: (?m)(?<!^ {0,1024}[#!].{0,1024})xy
; см. пример в regexplanet. Измените 1024
на желаемую максимальную длину строки. В большинстве разновидностей регулярных выражений нет квантификатора *
доступного внутри внешнего вида, но в Java могут использоваться удивительно фигурные скобки.