Как разделить на неэкранированную точку и проигнорировать двойную черную косую черту?

#java #regex

#java #регулярное выражение

Вопрос:

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

 data1\.d\\.ata2\\.da.ta3.data4
 

Эта строка должна быть разделена на подстроки for, например

 data1\
d\\.ata2\\
da.ta3
data4
 

Я не могу создать регулярное выражение для этого. Знаете ли вы, что это возможно?
Я попытался использовать следующее:

 (?<!\((\\){2,}))\. - not working
 

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

 "((?<!\\)\.)|((?=([^\\]*((\\\\) [^\\]*)))\.)";
 

Например data1\.d.ata2.da.ta3.data4 , разделено правильно:

 data1\
d.ata2
da.ta3
data4 
 

Но я не могу определить определение обратной косой черты даже число раз.
Можете ли вы мне помочь, пожалуйста?
Спасибо!

Ответ №1:

Вы можете извлечь эти строки с помощью

 (?s)(?:[^\.]|\.) 
 

Смотрите демонстрацию регулярных выражений. Подробные сведения:

  • (?s) — включите Pattern.DOTALL флаг, чтобы . он мог совпадать по строкам
  • (?:[^\.]|\.) — одно или несколько вхождений любого символа, отличного от and . , или a , за которым следует любой символ.

Смотрите демонстрацию Java:

 String line = "data1\\.d\.ata2.da\.ta3.data4";
Pattern p = Pattern.compile("(?s)(?:[^\\.]|\\.) ");
Matcher m = p.matcher(line);
List<String> res = new ArrayList<>();
while(m.find()) {
    res.add(m.group());
}
System.out.println(res);
// => [data1\, d.ata2, da.ta3, data4]
 

Ответ №2:

Вы можете использовать это регулярное выражение для получения совпадений:

 (?=[^.])[^.\]*(?:\.[^.\]*)*(?=.|$)
 

Демонстрация регулярных выражений

Демонстрация регулярных выражений:

  • (?=[^.]) : Убедитесь, что впереди есть символ без точки
  • [^.\]* : Сопоставьте 0 любого символа, который не является . не
  • (?:\.[^.\]*)* : Группа без захвата, которая соответствует обратной косой черте, за которой следует экранированный символ, и за которой должно следовать 0 или более любого символа, который не является . не a . Сопоставьте 0 или более из этой группы
  • (?=.|$) : Убедитесь, что у нас есть точка или конец строки впереди

Комментарии:

1. @ЭльфияВалиева Это не сработает, если escape-последовательность является первой в совпадении, тогда она будет пропущена. Посмотрите, как это не удается .

2. Это можно легко исправить, как вы можете видеть в отредактированном ответе. И это все равно будет быстрее, чем ваше регулярное выражение