Regex Java. Зачем использовать пересечение?
Я взял из этого руководства по оракулу в Java регулярное выражение, следующий бит:
Пересечения
Чтобы создать отдельный класс символов, соответствующий только символам, общим для всех его вложенных классов, используйте &&, как в [0-9&&[345]]. Это конкретное пересечение создает один класс символов, соответствующий только числам, общим для обоих классов символов: 3, 4 и 5.
Введите свое регулярное выражение: [0-9&&[345]] Введите строку ввода для поиска: 3 Я нашел текст "3", начиная с индекса 0 и заканчивая индексом 1.
Почему это будет полезно? Я имею в виду, если кто-то хочет сделать паттерн только 345, а не только [345] вместо "пересечения"?
Заранее спасибо.
1 ответ
Рассмотрим простую задачу: сопоставить английские согласные в строке. Вывести список всех согласных (или список диапазонов) можно одним из способов:
[B-DF-HJ-NP-TV-Zb-df-hj-np-tv-z]
Другой способ заключается в использовании осмотра:
(?=[A-Za-z])[^AEIOUaeiou]
(?![AEIOUaeiou])[A-Za-z]
Не уверен, есть ли другой способ сделать это без использования пересечения классов символов.
Решение для пересечения классов символов (Java):
[A-Za-z&&[^AEIOUaeiou]]
Для.NET пересечения нет, но есть вычитание класса символов:
[A-Za-z-[AEIOUaeiou]]
Я не знаю деталей реализации, но я не удивлюсь, если пересечение / вычитание класса символов будет быстрее, чем использование осмотра, которое является самой чистой альтернативой, если операция над классом символов недоступна.
Другое возможное использование - когда у вас есть предварительно созданный класс символов, и вы хотите удалить некоторые символы из него. Один случай, с которым я столкнулся, где пересечение классов может быть применимо, - это сопоставление всех пробельных символов, кроме новой строки.
Другой возможный вариант использования, как прокомментировал @beerbajay:
Я думаю, что встроенные классы символов являются основным вариантом использования, например
[\p{InGreek}&&\p{Ll}]
для строчных греческих букв.