JavaRush /جاوا بلاگ /Random-UR /جاوا میں باقاعدہ اظہار، حصہ 3

جاوا میں باقاعدہ اظہار، حصہ 3

گروپ میں شائع ہوا۔
ہم آپ کی توجہ کے لیے جاوا میں ریگولر ایکسپریشنز کے لیے ایک مختصر گائیڈ کا ترجمہ پیش کرتے ہیں، جو javaworld ویب سائٹ کے لیے Jeff Friesen نے لکھا ہے ۔ پڑھنے میں آسانی کے لیے ہم نے مضمون کو کئی حصوں میں تقسیم کیا ہے۔ Регулярные выражения в Java, часть 3 - 1جاوا میں ریگولر ایکسپریشنز، پارٹ 1 جاوا میں ریگولر ایکسپریشنز، پارٹ 2

Regex API کے ساتھ عام پروگرامنگ کے کاموں کو آسان بنائیں

اس مضمون کے حصے 1 اور 2 میں، آپ کو ریگولر ایکسپریشنز اور Regex API سے متعارف کرایا گیا تھا۔ آپ نے کلاس کے بارے میں سیکھا Patternاور ایسی مثالوں سے گزرے جو ریگولر ایکسپریشن کنسٹرکٹس کو ظاہر کرتی ہیں، لفظی اسٹرنگ کا استعمال کرتے ہوئے سادہ پیٹرن کی مماثلت سے لے کر رینجز، باؤنڈری میچرز اور کوانٹیفائرز کا استعمال کرتے ہوئے مزید پیچیدہ میچنگ تک۔ اس اور اس کے بعد کے حصوں میں ہم ان مسائل پر غور کریں گے جن کا پہلے حصے میں احاطہ نہیں کیا گیا، ہم کلاسوں کے متعلقہ طریقوں کا مطالعہ کریں گے Pattern، Matcherاور PatternSyntaxException۔ آپ دو افادیتیں بھی سیکھیں گے جو عام پروگرامنگ کے مسائل کو آسان بنانے کے لیے ریگولر ایکسپریشنز کا استعمال کرتی ہیں۔ پہلا دستاویز کے لیے کوڈ سے تبصرے نکالتا ہے۔ دوسرا دوبارہ قابل استعمال کوڈ کی ایک لائبریری ہے جسے لغوی تجزیہ کرنے کے لیے ڈیزائن کیا گیا ہے - اسمبلرز، کمپائلرز اور اسی طرح کے سافٹ ویئر کا ایک لازمی جزو۔

سورس کوڈ ڈاؤن لوڈ کرنا

آپ اس آرٹیکل میں ڈیمو ایپلیکیشنز کے لیے تمام سورس کوڈ (Jeff Friesen for JavaWorld کا تخلیق کردہ) یہاں سے حاصل کر سکتے ہیں ۔

Regex API سیکھنا

Pattern، Matcherاور PatternSyntaxExceptionوہ تین کلاسز ہیں جو Regex API بناتے ہیں۔ ان میں سے ہر ایک ایسے طریقے فراہم کرتا ہے جو آپ کو اپنے کوڈ میں ریگولر ایکسپریشنز استعمال کرنے کی اجازت دیتا ہے۔

پیٹرن کلاس کے طریقے

کلاس کی ایک مثال Patternایک مرتب شدہ ریگولر ایکسپریشن ہے، جسے پیٹرن بھی کہا جاتا ہے۔ پیٹرن میچنگ آپریشنز کی کارکردگی کو بہتر بنانے کے لیے باقاعدہ اظہارات مرتب کیے جاتے ہیں۔ درج ذیل جامد طریقے تالیف کی حمایت کرتے ہیں۔
  • Pattern compile(String regex)مواد کو regexایک انٹرمیڈیٹ نمائندگی میں مرتب کرتا ہے جو ایک نئے میں محفوظ ہوتا ہے Pattern۔ یہ طریقہ یا تو کامیاب ہونے پر کسی شے کا حوالہ لوٹاتا ہے، یا PatternSyntaxExceptionاگر غلط ریگولر ایکسپریشن نحو کا پتہ چلا ہے تو مستثنیٰ پھینک دیتا ہے۔ کلاس کا کوئی بھی آبجیکٹ جو اس آبجیکٹ Matcherکے ذریعہ استعمال ہوتا ہے Patternیا اس سے واپس آتا ہے وہ اپنی ڈیفالٹ سیٹنگز کا استعمال کرتا ہے، جیسے کیس حساس تلاش۔ ایک مثال کے طور پر، کوڈ کا ٹکڑا Pattern p = Pattern.compile("(?m)^\\."); ایک ایسی چیز بناتا ہے Patternجو ڈاٹ کیریکٹر سے شروع ہونے والے تاروں سے ملنے کے لیے ایک ریگولر ایکسپریشن کی مرتب کردہ نمائندگی کو اسٹور کرتا ہے۔

  • Pattern compile(String regex, int flags) решает ту же задачу, что и Pattern compile(String regex), но с учетом flags: набора битовых констант для побитовых флагов типа ИЛИ. В классе Pattern объявлены константы CANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINES, которые можно комбинировать при помощи побитового ИЛИ (например, CASE_INSENSITIVE | DOTALL) и передать в аргументе flags.

  • За исключением CANON_EQ, LITERAL и UNICODE_CHARACTER_CLASS, эти константы являются альтернативой вложенных флаговым выражениям, продемонстрированным в части 1. При обнаружении флаговой константы, отличающейся от определенных в классе Pattern, метод Pattern compile(String regex, int flags) генерирует исключение java.lang.IllegalArgumentException. Например, Pattern p = Pattern.compile("^\\.", Pattern.MULTILINE); эквивалентно предыдущему примеру, причем константа Pattern.MULTILINE и вложенное флаговое выражение (?m) делают одно и то же.
Иногда бывает необходимо получить копию исходной строки регулярного выражения, скомпorрованного в an object Pattern, вместе с используемыми им флагами. Для этого можно вызвать следующие методы:
  • String pattern() возвращает исходную строку регулярного выражения, скомпorрованную в an object Pattern.

  • int flags() возвращает флаги an object Pattern.
После получения an object Pattern, он обычно используется для получения an object Matcher, для выполнения операций поиска по шаблону. Метод Matcher matcher(Charsequence input) создает an object Matcher, ищущий в тексте input соответствие шаблону an object Pattern. При вызове он возвращает ссылку на этот an object Matcher. Например, команда Matcher m = p.matcher(args[1]); возвращает Matcher для an object Pattern, на который ссылается переменная p.
Одноразовый поиск
Метод static boolean matches(String regex, CharSequence input) класса Pattern позволяет сэкономить на создании an objectов Pattern и Matcher при одноразовом поиске по шаблону. Этот метод возвращает true, если в input находится соответствие шаблону regex, в противном случае он возвращает false. Если в регулярном выражении содержится синтаксическая ошибка, метод генерирует исключение PatternSyntaxException. Например, System.out.println(Pattern.matches("[a-z[\\s]]*", "all lowercase letters and whitespace only")); выводит true, подтверждая, что во фразе all lowercase letters and whitespace only содержатся только пробелы и символы в нижнем регистре.
Регулярные выражения в Java, часть 3 - 2

Разбиение текста

Большинству разработчиков приходилось хоть раз писать code для разбиения входного текста на составные части, например, преобразовывать текстовую учетную запись сотрудника в набор полей. Класс Pattern предоставляет возможность более удобного решения этой утомительной задачи, при помощи двух методов разбиения текста:
  • Метод String[] split(CharSequence text, int limit) разбивает text в соответствии с найденными соответствиями шаблону an object Pattern и возвращает результаты в массиве. Каждый элемент массива задает текстовую последовательность, отделенную от следующей последовательности соответствующим шаблону фрагментом текста (or концом текста). Элементы массива находятся в том же порядке, в котором они встречаются в text.

    В этом методе, количество элементов массива зависит от параметра limit, контролирующего также и число искомых соответствий.

    • При положительном значении выполняется поиск не более чем limit-1 соответствий, а длина массива не превышает limit элементов.
    • При отрицательном значении выполняется поиск всех возможных соответствий, и длина массива может быть произвольной.
    • При равном нулю значении выполняется поиск всех возможных соответствий, длина массива может быть произвольной, а пустые строки в конце отбрасываются.

  • Метод String[] split(CharSequence text) вызывает предыдущий метод с 0 в качестве аргумента limit и возвращает результат его вызова.
Ниже приведены результаты работы метода split(CharSequence text) по решению задачи расщепления учетной записи сотрудника на отдельные поля имени, возраста, почтового address и salaries:
Pattern p = Pattern.compile(",\\s");
String[] fields = p.split("John Doe, 47, Hillsboro Road, 32000");
for (int i = 0; i < fields.length; i++)
   System.out.println(fields[i]);
В вышеприведенном codeе описано регулярное выражение для поиска знака запятой, за которым непосредственно следует одиночный символ пробела. Вот результаты его выполнения:
John Doe
47
Hillsboro Road
32000

Предикаты шаблонов и API Streams

В Java 8 в классе Pattern появился метод Predicate asPredicate() . Этот метод создает предикат (функцию с булевым meaningм), используемый для поиска по шаблону. Использование этого метода показано в следующем фрагменте codeа:
List progLangs = Arrays.asList("apl", "basic", "c", "c++", "c#", "cobol", "java", "javascript", "perl", "python", "scala");
Pattern p = Pattern.compile("^c");
progLangs.stream().filter(p.asPredicate()).forEach(System.out::println);
Этот code создает список названий языков программирования, затем компorрует шаблон для поиска всех названий, начинающихся с буквы c. Последняя из вышеприведенных строк codeа реализует получение последовательного потока данных с этим списком в качестве источника. Он устанавливает фильтр, использующий булеву функцию asPredicate(), которая возвращает true, когда название начинается с буквы c и выполняет итерацию по потоку, выводя подходящие названия в стандартный поток вывода. Эта последняя строка эквивалентна следующему обычному циклу, знакомому вам по приложению RegexDemo из части 1:
for (String progLang: progLangs)
   if (p.matcher(progLang).find())
      System.out.println(progLang);

Методы класса Matcher

Экземпляр класса Matcher описывает механизм выполнения операций поиска по шаблону в последовательности символов путем интерпретации скомпorрованного регулярного выражения класса Pattern. Объекты класса Matcher поддерживают различные виды операций поиска по шаблону:
  • Метод boolean find() ищет во входном тексте следующее совпадение. Этот метод начинает просмотр or в начале заданного текста, or на первом символе после предыдущего совпадения. Второй вариант возможен только если предыдущий вызов этого метода вернул true и сопоставитель не был сброшен. В любом случае, в случае успешного поиска возвращается булево meaning true. Пример этого метода вы можете найти в RegexDemo из части 1.

  • Метод boolean find(int start) сбрасывает сопоставитель и ищет в тексте следующее совпадение. Просмотр начинается с позиции, задаваемой параметром start. В случае успешного поиска возвращается булево meaning true. Например, m.find(1); просматривает текст, начиная с позиции 1 (позиция 0 игнорируется). Если параметр start содержит отрицательное meaning or meaning, превышающее длину текста сопоставителя, метод генерирует исключение java.lang.IndexOutOfBoundsException.

  • Метод boolean matches() пытается сопоставить с шаблоном весь текст. Он возвращает булево meaning true, если весь текст соответствует шаблону. Например, code Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches()); выводит false, поскольку символ ! не является словообразующим символом.

  • Метод boolean lookingAt() пытается сопоставить с шаблоном заданный текст. Этот метод возвращает true, если любая часть текста соответствует шаблону. В отличие от метода matches();, весь текст не должен соответствовать шаблону. Например, Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.lookingAt()); выведет true, поскольку начало текста abc! состоит только из словообразующих символов.

В отличие от an objectов класса Pattern, an objectы класса Matcher сохраняют информацию о состоянии. Иногда может понадобиться сбросить сопоставитель, чтобы очистить эту информацию после окончания поиска по шаблону. Для сброса сопоставителя существуют следующие методы:
  • Метод Matcher reset() сбрасывает состояние сопоставителя, включая позицию для добавления в конец (сбрасываемую в 0). Следующая операция поиска по шаблону начинается в начале текста сопоставителя. returnsся link на текущий an object Matcher. Например, m.reset(); сбрасывает сопоставитель, на который ссылается m.

  • Метод Matcher reset(CharSequence text) сбрасывает состояние сопоставителя и задает новый текст сопоставителя, равный text. Следующая операция поиска по шаблону начинается в начале нового текста сопоставителя. returnsся link на текущий an object Matcher. Например, m.reset("new text"); сбрасывает сопоставитель, на который ссылается m и задает в качестве нового текста сопоставителя meaning "new text".

Регулярные выражения в Java, часть 3 - 3

Добавление текста в конец

Позиция сопоставителя для добавления в конец задает начало текста сопоставителя, добавляемого в конец an object типа java.lang.StringBuffer. Эту позицию используют следующие методы:
  • Метод Matcher appendReplacement(StringBuffer sb, String replacement) читает символы текста сопоставителя и присоединяет их в конец an object StringBuffer, на который ссылается аргумент sb. Этот метод прекращает чтение на последнем символе, предшествующем предыдущему соответствию шаблону. Далее, метод добавляет символы из an object типа String, на который ссылается аргумент replacement, в конец an object StringBuffer (строка replacement может содержать ссылки на текстовые последовательности, захваченные во время предыдущего поиска; они указываются при помощи символов ($) и номеров захватываемых групп). Наконец, метод устанавливает meaning позиции сопоставителя для добавления в конец равным позиции последнего совпавшего символа плюс единица, после чего возвращает ссылку на текущий сопоставитель.

  • Метод Matcher appendReplacement(StringBuffer sb, String replacement) генерирует исключение java.lang.IllegalStateException, если сопоставитель еще не находил соответствия or предыдущая попытка поиска завершилась неудачно. Он генерирует исключение IndexOutOfBoundsException, если строка replacement задает отсутствующую в шаблоне захватываемую группу).

  • Метод StringBuffer appendTail(StringBuffer sb) добавляет весь текст в an object StringBuffer и возвращает ссылку на этот an object. После последнего вызова метода appendReplacement(StringBuffer sb, String replacement), вызовите метод appendTail(StringBuffer sb), чтобы скопировать оставшийся текст в an object StringBuffer.

Захватываемые группы
Как вы помните из части 1, захватываемая группа — это последовательность символов, заключенная в метасимволы круглых скобок (()). Цель этой конструкции состоит в сохранении найденных символов для дальнейшего повторного использования во время поиска по шаблону. Все символы из захватываемой группы рассматриваются во время поиска по шаблону How единое целое.
В следующем codeе выполняется вызов методов appendReplacement(StringBuffer sb, String replacement) и appendTail(StringBuffer sb для замены в исходном тексте всех вхождений последовательности символов cat на caterpillar:
Pattern p = Pattern.compile("(cat)");
Matcher m = p.matcher("one cat, two cats, or three cats on a fence");
StringBuffer sb = new StringBuffer();
while (m.find())
   m.appendReplacement(sb, "$1erpillar");
m.appendTail(sb);
System.out.println(sb);
Использование захватываемой группы и ссылки на неё в замещающем тексте указывает программе вставлять erpillar после каждого вхождения cat. Результат выполнения данного codeа выглядит следующим образом: one caterpillar, two caterpillars, or three caterpillars on a fence

Замена текста

Класс Matcher предоставляет нам два метода для текстовой замены, дополняющих метод appendReplacement(StringBuffer sb, String replacement). С помощью этих методов можно заменять or первое вхождение [замещаемого текста] or все вхождения:
  • Метод String replaceFirst(String replacement) сбрасывает сопоставитель, создает новый an object String, копирует в эту строку все символы текста сопоставителя (вплоть до первого совпадения), добавляет в её конец символы из replacement, копирует в строку оставшиеся символы и возвращает an object String (в строке replacement можно указывать ссылки на захваченные во время предыдущего поиска текстовые последовательности, при помощи символов доллара и номеров захватываемых групп).

  • Метод String replaceAll(String replacement) действует аналогично методу String replaceFirst(String replacement), но заменяет символами из строки replacement всё найденные совпадения.

Регулярное выражение \s+ служит для поиска одного or более пробельных символов во входном тексте. Ниже, мы воспользуемся этим регулярным выражением и вызовем метод replaceAll(String replacement) для удаления дублирующихся пробелов:
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher("Удаляем      \t\t лишние пробелы.   ");
System.out.println(m.replaceAll(" "));
Вот результаты: Удаляем лишние пробелы. Регулярные выражения в Java, часть 4 Регулярные выражения в Java, часть 5
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION