Как использовать регулярные выражения, чтобы соответствовать всему перед определенным типом слова - PullRequest
17 голосов
/ 18 февраля 2009

Я новичок в регулярных выражениях.

Можно ли сопоставить все перед словом, соответствующим определенным критериям:

* 1005 Е.Г. *

ЭТО ТЕСТ - - +++ Это тест

Я бы хотел встретить слово, которое начинается с заглавной буквы, а следующий символ - строчной. Это правильное слово. Затем я хотел бы удалить все до этого слова.

Приведенный выше пример должен дать: Это тест

Я хочу выполнять эту обработку, пока она не найдет правильное слово и не остановится.

Любая помощь будет оценена.

Спасибо

Ответы [ 5 ]

47 голосов
/ 18 февраля 2009

Заменить

^.*?(?=[A-Z][a-z])

с пустой строкой. Это работает для ввода ASCII. Для ввода без ASCII (Unicode, другие языки) применяются разные стратегии.

Объяснение

.*?    Everything, until
(?=    followed by
[A-Z]  one of A .. Z and
[a-z]  one of a .. z
)

Вариант с поддержкой Unicode для Java будет следующим:

^.*?(?=\p{Lu}\p{Ll})
3 голосов
/ 18 февраля 2009

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

import java.util.regex.*;

public class Test
{
    public static void main(String args[])
    {
        Pattern pattern = Pattern.compile("[A-Z][a-z].*");

        String original = "THIS IS A TEST - - +++ This is a test";
        Matcher match = pattern.matcher(original);
        if (match.find())
        {
            System.out.println(match.group());
        }
        else
        {
            System.out.println("No match");
        }        
    }
}

РЕДАКТИРОВАТЬ: Оригинальный ответ

Похоже, что он делает правильные вещи:

import java.util.regex.*;

public class Test
{
    public static void main(String args[])
    {
        Pattern pattern = Pattern.compile("^.*?([A-Z][a-z].*)$");

        String original = "THIS IS A TEST - - +++ This is a test";
        String replaced = pattern.matcher(original).replaceAll("$1");

        System.out.println(replaced);
    }
}

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

Сказанное выше не с "*** FOO *** I am fond of peanuts", потому что «я» не будет считаться правильным словом. Если вы хотите это исправить, замените [a-z] на [a-z \ s], что позволит использовать пробел вместо буквы.

1 голос
/ 18 февраля 2009

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

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

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

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

Так что ему понадобится документация - и если кто-то, находящийся на том же уровне, столкнется с ней, он не сможет изменить ее без знаний вне своей области, даже с документацией.

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

public String getRealText(String scanMe) {
    for(int i=0 ; i < scanMe.length ; i++)
        if( isUpper(scanMe[i]) && isLower(scanMe[i+1]) )
            return scanMe.subString(i);
return null; }

Я имею в виду, что это 5 строк, но это просто, доступно для чтения и быстрее, чем большинство (все?) Парсеры RE. После того как вы завернули регулярное выражение в метод и прокомментировали его, разница в размере не поддается измерению. Разница во времени - хорошо для автора, очевидно, было бы намного меньше времени - как это могло бы быть для следующего парня, который сталкивается с его кодом.

И эта строковая операция является одной из тех, которые еще проще в C с указателями - и это было бы еще быстрее, поскольку функции тестирования являются макросами в C.

Кстати, убедитесь, что вы ищете пробел во втором слоте, а не просто строчную переменную, иначе вы пропустите все строки, начинающиеся со слов A или I.

0 голосов
/ 18 февраля 2009

([A-Z] [A-Z] +.)

будет соответствовать:

Это текст

0 голосов
/ 18 февраля 2009

тогда вы можете сделать что-то вроде этого

'.*([A-Z][a-z].*)\s*'

.* matches anything
( [A-Z] #followed by an uper case char 
  [a-z] #followed by a lower case 
  .*)   #followed by anything
  \s*   #followed by zeror or more white space

То, что вы ищете, я думаю

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...