Используя regex к строке совпадения между двумя строками, в то время как, исключая строки

Следование за предыдущим вопросом, в котором я спросил:

Как я могу использовать регулярное выражение для соответствия тексту, который является между двумя строками, где те две строки самостоятельно включаются две других строки с какой-либо суммой текста между внутренними и внешними строками включения?

Я получил этот ответ:

/outer-start.*?inner-start(.*?)inner-end.*?outer-end/

Я теперь хотел бы знать, как исключить определенные строки из текста между внешними строками включения и внутренними строками включения.

Например, если у меня есть этот текст:

внешний - запускаются, некоторый внутренний текст - запускают text-that-i-want внутренний конец еще некоторый текстовый внешний конец

Я хотел бы, 'чтобы некоторый текст' и 'еще некоторый текст' не содержали 'нежелательное' слово.

Другими словами, это в порядке:

внешний - запускаются, некоторый требуемый внутренний текст - запускают text-that-i-want внутренний конец еще некоторый требуемый текстовый внешний конец

Но это не в порядке:

внешний - запускаются, некоторый внутренний ненужный текст - запускают text-that-i-want внутренний конец еще некоторый внешний конец ненужного текста

Или объяснить далее, выражение между внешними и внутренними разделителями в предыдущем ответе выше должно исключить 'нежелательное' слово.

Действительно ли это легко соответствовать использованию regexes?

5
задан Community 23 May 2017 в 12:18
поделиться

5 ответов

Замените первую и последнюю (но не среднюю) .*? на (?:(?!нежелательно))*?. (Где (?:...) является не захватывающей группой, а (?!...) - отрицательной.)

Однако, это быстро заканчивается угловыми случаями и предостережениями в любом реальном (вместо примера) использовании, и если вы спросите о том, что вы на самом деле делаете (с реальными примерами, даже если они упрощены, вместо выдуманных примеров), вы, скорее всего, получите лучшие ответы.

[112207].
5
ответ дан 14 December 2019 в 01:09
поделиться

Попробуйте заменить последний .*? на другой: (?!(.*нежелательный текст.*))

Сработало?

0
ответ дан 14 December 2019 в 01:09
поделиться

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

/outer-start(?:u(?!nwanted)|[^u])*?inner-start(.*?)inner-end.*?outer-end/

Ключ состоит в том, чтобы разделить "ненужное" на ("u", за которым не следует "nwanted") или (не "u"). Это позволит шаблону продвигаться вперед, но все равно найдет и отвергнет все "нежелательные" строки.

Люди могут начать ненавидеть ваш код, если вы сделаете большую часть этого. ;)

.
1
ответ дан 14 December 2019 в 01:09
поделиться

Вы можете заменить .*? на

 ([^u]|u[^n]|un[^w]|unw[^a]|unwa[^n]|unwan[^t]|unwant[^e]|unwante[^d])*?

Это решение в "чистом" регексе; язык, который вы используете, может позволить вам использовать более элегантную конструкцию.

.
1
ответ дан 14 December 2019 в 01:09
поделиться

Лучший вопрос, который можно задать себе, чем "как это сделать с регулярными выражениями?" - это "как это решить эту проблему? Другими словами, не зацикливайтесь на попытках решить большую проблему с регулярными выражениями. Если вы можете решить половину проблемы с регулярными выражениями, сделайте это, а вторую половину решите другим регулярным выражением или другой техникой.

Например, пропустите данные, получив все совпадения, игнорируя ненужный текст (читать: получите результаты как с ненужным текстом, так и без него). Затем пропустите сокращенный набор данных и удалите те результаты, в которых есть нежелательный текст. Такое решение легче написать, проще понять и проще поддерживать с течением времени. И для любой проблемы, которую вам, скорее всего, придется решать при таком подходе, оно будет достаточно быстрым.

2
ответ дан 14 December 2019 в 01:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: