Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Вытащить из текста всё, не удовлетворяющее регулян


Автор: startpoint 12.8.2012, 14:15
Сразу к делу:
Код
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {

        String file = "package my.example.model.base;\n" + 
             "// Generated Aug 11, 2012 7:13:37 PM by Hibernate Tools 3.2.4.GA\n" + 
             "\n" + 
             "\n" + 
             "\n" + 
             "/**\n" + 
             " * FileBase generated by hbm2java\n" + 
             " */\n" + 
             "public class FileBase  implements java.io.Serializable {\n" + 
             "\n" + 
             "    private Integer id;\n" + 
             "    private int hostId;\n" + 
             "    private int date;\n" + 
             "\n" + 
             "    public FileBase() {\n" + 
             "    }\n" + 
             "\n" + 
             "    \n" + 
             "    public FileBase(int hostId) {\n" + 
             "        this.hostId = hostId;\n" + 
             "    }\n" + 
             "\n" + 
             "    public FileBase(int hostId, int date) {\n" + 
             "       this.hostId = hostId;\n" + 
             "       this.date = date;\n" + 
             "    }\n" + 
             "   \n" + 
             "    public Integer getId() {\n" + 
             "        return this.id;\n" + 
             "    }\n" + 
             "    \n" + 
             "    public void setId(Integer id) {\n" + 
             "        this.id = id;\n" + 
             "    }\n" + 
             "\n" + 
             "    public int getHostId() {\n" + 
             "        return this.hostId;\n" + 
             "    }\n" + 
             "    \n" + 
             "    public void setHostId(int hostId) {\n" + 
             "        this.hostId = hostId;\n" + 
             "    }\n" + 
             "\n" + 
             "    public int getDate() {\n" + 
             "        return this.date;\n" + 
             "    }\n" + 
             "    \n" + 
             "    public void setDate(int date) {\n" + 
             "        this.date = date;\n" + 
             "    }\n" + 
             "}";
        
        Pattern pattern = Pattern.compile("package[^;]+;|// Generated[^\n]+|/\\*\\*| \\*[^\n]+| \\*/|public class[^\n]+|public FileBase\\([^)]*\\)\\s*\\{[^}]*}|private [^\n]+|}$", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(file);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

Переменная file содержит исходный код класса FileBase, который был Generated by Hibernate Tools. Однако он мне в таком виде не нужен. Ниже, идёт регулярное выражение, которое вытаскивает из этого класса только то, что мне нужно. Именно оно и делает "класс моей мечты".  Если приглядется, то оно просто содержит в себе кучу более менее простых регулярок, разделённых альтернативой. На выходе я получаю следующее:
Код

package my.example.model.base;
// Generated Aug 11, 2012 7:13:37 PM by Hibernate Tools 3.2.4.GA
/**
 * FileBase generated by hbm2java
 */
public class FileBase  implements java.io.Serializable {
private Integer id;
private int hostId;
private int date;
public FileBase() {
    }
public FileBase(int hostId) {
        this.hostId = hostId;
    }
public FileBase(int hostId, int date) {
       this.hostId = hostId;
       this.date = date;
    }
}

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

Автор: startpoint 16.8.2012, 11:54
я чо, вопрос из области фантастики задал ?

Автор: korian 16.8.2012, 22:58
Цитата(startpoint @  16.8.2012,  10:54 Найти цитируемый пост)
я чо, вопрос из области фантастики задал ? 

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

Автор: jk1 17.8.2012, 10:06
Цитата

обатное это уже не регулярки


Есть в регулярках такая штука, называется negative lookahead. Если Ваш "абстрактный движок" их поддерживает, то можно таким образом матчить текст, не удовлетворяющий условию. Пример для java-регэкспов:

Код

 String regex = "John (?!Smith)[A-Z]\\w+";
    Pattern pattern = Pattern.compile(regex);

    String candidate = "I think that John Smith ";
    candidate += "is a fictional character. His real name ";
    candidate += "might be John Jackson, John Westling, ";
    candidate += "or John Holmes for all we know.";

    Matcher matcher = pattern.matcher(candidate);

    String tmp = null;

    while (matcher.find()) {
      tmp = matcher.group();
      System.out.println("MATCH:" + tmp);
    }

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)