Регулярное выражение, которое соответствует двухстрочному тексту, не содержащему пробела или определенной строки

Я ищу регулярное выражение, которое соответствует строке из двух строк со следующей характеристикой:

[any number of any character]"[any number of any character][not a space and not a backslash followed by the char n]"
[any number of spaces]"[not a space][any number of any character]"

то есть оно должно соответствовать: 1)

abc def "ghi jkl"
     "mno pqr"

но нет 2)

abc def "ghi jkl "
     "mno pqr"

ни 3)

abc def "ghi jkl"
     " mno pqr"

ни 4)

abc def "ghi jkl\n"
     "mno pqr"

Я использую регулярное выражение: ".*[^\s]"\s+"[^\s].*"

Это хорошо работает с 1), 2) и 3), но явно не с 4).

Попробуйте: "\S.*\S"\s+"\S.*\S"? Вам нужно полное совпадение? Вы хотите извлечь те, что в кавычках? ^(?m)[^"\r\n]+"\S.*\S"\s+"\S.*\S"\s*$. Это действительно? abc def "s" "s"

user24714692 17.06.2024 00:23

Ваше недавнее изменение изменено с [not a space and not the string '\n'] на [not a space and not a backslash followed by the char n]. Оба сбивают с толку, но особенно текущий, потому что обратная косая черта, за которой следует символ «n», означает два символа, а не экранированный «n»; то есть символ новой строки (\n). Предлагаю [a character other than a space or newline character].

Cary Swoveland 17.06.2024 08:47

<<обратная косая черта, за которой следует символ n>> означает обратную косую черту, за которой следует символ n, буквально, т. е. 2 символа, а не новую строку.

Andrea Giudiceandrea 17.06.2024 08:54

Вы могли бы избежать всей путаницы в своем вопросе, если бы правильно написали строки в кавычках. Например, вместо abc def "ghi jkl\n" надо было написать "abc def \"ghi jkl\\n\"". То, что вы сделали, похоже на запись массива как 1, 2, 3, а не [1, 2, 3]. Я понижаю голосование за неясность вашего вопроса.

Cary Swoveland 17.06.2024 22:07

Я только что перечислил текст, который должен и не должен совпадать. В тексте есть строка \n" буквально, а не \\n\".

Andrea Giudiceandrea 17.06.2024 23:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
104
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если вы хотите извлечь эти две подстроки, вы можете использовать:

^(?m)[^"\r\n]+"(\S.*\S)"\s+"(\S.*\S)"\s*$

а если нет:

^(?m)[^"\r\n]+"\S.*\S"\s+"\S.*\S"\s*$

К сожалению, предложенное регулярное выражение некорректно совпадает, даже если текст, заключенный в двойные кавычки в первой строке, заканчивается обратной косой чертой, за которой следует буква n, например abc def "ghi jkl\n" regex101.com/r/EArk1N/1

Andrea Giudiceandrea 17.06.2024 08:00

Отредактировал мой ответ на основе отрицательного анализа Sina-sarshar-pour ответа:

.*[^\s](?<!\b\\n\b)"\s+"[^\s].*

https://stackoverflow.com/a/78631164/1856745

Тесты:

Возвышенный текст.

https://regex101.com/r/nb0dQy/1

https://regexr.com/81o2m

К сожалению, предлагаемое регулярное выражение некорректно не соответствует, даже если текст, заключенный в двойные кавычки в первой строке, заканчивается обратной косой чертой, например abc def "ghi jkl\" regex101.com/r/aJ3iG1/1, и если он заканчивается на n не предшествует обратная косая черта, например abc def "ghi jkln" regex101.com/r/JmTHwR/1

Andrea Giudiceandrea 17.06.2024 08:16

Этого не было в первой версии вашего вопроса. Будет ли шаблон вашего текста выглядеть так: [любое количество любых символов]"[любое количество любых символов][(не пробел) и ((не обратная косая черта) или (не обратная косая черта, за которой следует символ n))] " [любое количество пробелов]"[не пробел][любое количество любых символов]"

Danielson Alves Júnior 17.06.2024 08:38

В первой версии я написал <<не пробел и не строку '\n'>>, подразумевая <<не пробел и не обратную косую черту, за которой следовал символ n>>

Andrea Giudiceandrea 17.06.2024 08:42

Насколько я понимаю, вы хотите определить, соответствуют ли строки следующему регулярному выражению.

(?x)     # invoke extended (aka free-spacing) mode
^        # match beginning of the string
[^"\n]*  # match zero or more chars other than line terminators
         # and double-quotes
"        # match a double-quote
[^"\n]*  # match zero or more chars other than line terminators
         # and double-quotes
(?<!     # begin a negative lookbehind
  \      # match a space
  |      # or
  \\n    # match a backslash followed by n
)        # end negative lookbehind
"        # match a double-quote
\n       # match a newline
\ *      # match zero or more spaces
"        # match double-quote
[^ "\n]  # match a character other than a space, double-quote or newline
[^"\n]*  # match zero or more chars other than line terminators 
         # and double-quotes
"        # match a double-quote
\n?      # optionally match a newline
$        # match end of string

Я написал это в расширенном режиме (то есть со свободным интервалом), чтобы прояснить свои предположения. Если какие-либо из них неверны, вы можете внести необходимые изменения. Вы написали, например, «любое количество любых символов». Я предположил, что вы на самом деле имели в виду «любое количество любых символов, кроме двойных кавычек и новых строк». Точно так же я предположил, что фраза «без пробела или обратной косой черты, за которой следует «n»» означает, что строка, предшествующая второй двойной кавычке, не может заканчиваться пробелом или обратной косой чертой, за которой следует «n».

Это регулярное выражение соответствует следующим двум (двухстрочным) строкам.

a c"d1 %"
   "&g i"

"9"
"&"

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

д а"фе" "3ч дж"

c"d1 \n" "&г я"

а"де f%x" "&12"

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

Обратите внимание, что я выбрал механизм регулярных выражений PCRE2 по ссылке выше, но предложенное мной регулярное выражение не использует каких-либо расширенных функций регулярных выражений, поэтому оно должно быть совместимо с большинством механизмов регулярных выражений.

1

К сожалению, предложенное регулярное выражение некорректно совпадает, даже если текст, заключенный в двойные кавычки в первой строке, заканчивается обратной косой чертой, за которой следует буква n, например abc def "ghi jkl\n" regex101.com/r/CKSDKv/1

Andrea Giudiceandrea 17.06.2024 08:43

Я понимаю разницу между символом новой строки и последовательностью двух символов, состоящей из обратной косой черты и буквы «n», поэтому я написал <<не пробел и не строка '\n'>> и, чтобы быть более понятным, Я отредактировал его <<не пробел и не обратная косая черта, за которой следует символ n>>, что, я думаю, означает не пробел и не обратную косую черту, за которой следует символ n буквально, т.е. 2 символа (иначе я бы написал <<не a пробел, а не новая строка>>.

Andrea Giudiceandrea 17.06.2024 11:48
Ответ принят как подходящий

Использование негативного ретроспективного анализа

.*".*(?<! |\\n)"\n\s*"(?! )..*"

Ты прав. если вы измените \s+ на \s*, это тоже сработает. В вопросе указано любое количество пробелов во второй строке, но я использовал \s+, который соответствует строке только в том случае, если во второй строке существует хотя бы один пробел. Так что моя ошибка. Новый ответ будет Демо.*".*((?<! |\\n))"\n\s*"(?! )..*"

Sina Sarshar Pour 17.06.2024 09:06

Я обновил свой первоначальный ответ

Sina Sarshar Pour 17.06.2024 09:13

Обновил свой ответ на основе вашего отрицательного прогноза!

Danielson Alves Júnior 17.06.2024 09:32

В видимости вы можете избежать негативного просмотра, написав .*".*((?<! |\\n))"\n\s*"[^ \n].*".

Cary Swoveland 18.06.2024 21:03

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

Cary Swoveland 18.06.2024 21:16

Отличный улов @CarySwoveland! Простое удаление группы захвата дает большой выигрыш в производительности (на 1000 вызовов меньше на 30 миллисекунд). Удаление отрицательного просмотра вперед также дает выигрыш в производительности, но очень небольшой (0,2 миллисекунды на 1000 вызовов).

Sina Sarshar Pour 19.06.2024 01:04

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

Cary Swoveland 19.06.2024 01:08

@CarySwoveland, эти разговоры в комментариях отлично подходят для будущих читателей. Довольно мало информации о производительности. Я бы хотел сохранить это

Sina Sarshar Pour 19.06.2024 01:14

Тем временем я обновил свой первоначальный ответ, чтобы удалить групповые снимки.

Sina Sarshar Pour 19.06.2024 01:15

Другие вопросы по теме