[RESOLVIDO] REGEX para mascaras de arquivos

Olá a todos os colegas do GUJ… sou novo com Regex…

Dei uma pesquisada por ai(e aqui) para algo que to precisando porem só achei coisas que me dão o suporte na API… porem to com dificuldade na criação da logica da Expressão…

o cenario…
o sistema trabalha com pesquisa de arquivos em servidor remoto pelo nome… tenho as chamadas “máscaras de arquivos” que seriam as minhas expressões…

EX: no servidor digamos que eu tenho os arquivos
teste_arquivo_formatado.pdf
relatorio_gerencial_julho.doc

na pesquisa as máscaras teriam a possibilidade de trabalhar com os curingas “?”(para uma posição de caractere), “.” e “*” (ambos para caracteres com 0 ou mais ocorrencias), preciso ainda que seja algo dinamico… pois algo fixo ja tem… porem pouco confiavel e algumas mascaras não encontram os arquivos, e muito ruim de mexer no codigo.

Mais exemplos: vou pesquisar no diretorio pelas seguintes mascaras (dentre outras muitas):

[color=red]???atoriojulho.[/color] --> encontraria o arquivo .doc
[color=red]*_gerencial_julho.doc[/color] --> encontraria o arquivo .doc
[color=red]teste*[/color] --> encontraria o arquivo .pdf
[color=red].[/color] --> encontraria todos arquivos do diretorio e por ai vai…

Já sei tambem que tenho que trabalhar com as duas classes do pacote Util…
java.util.regex.Matcher;
java.util.regex.Pattern

Alguem pode me ajudar com alguma coisa…
Abraço e obrigado…

De onde vc tirou [quote]terião[/quote]?

Se vc estivesse fazendo sua busca por exemplo do command do windows, dir . /s resolveria seu problema? Se sim vc poderia trabalhar com a classe Process

Esta é a primeira vez que vejo a palavra “terião”. Lembra um nome de comida japonesa.

De qualquer forma, é relativamente simples você usar expressões regulares para máscaras de arquivos. Basta lembrar que o equivalente do “" de máscaras de arquivos é a expressão regular ".”, o equivalente do “.” para máscaras de arquivos é a expressão regular “\.” e o equivalente do “?” é a expressão regular “.”.

Além disso, os seguintes caracteres, que são relevantes para expressões regulares mas não o são para máscaras de arquivos, devem ser protegidos:

“^” --> “\^”
“|” --> “\|”
“(” --> “\(”
“)” --> “\)”
“[” --> “\[”
“]” --> “\]”
“\” --> “\\”
“$” --> “\$”
“+” --> “\+”

[quote=avsouza]De onde vc tirou [quote]terião[/quote]?

Se vc estivesse fazendo sua busca por exemplo do command do windows, dir . /s resolveria seu problema? Se sim vc poderia trabalhar com a classe Process[/quote]

Quanto ao “terião” as vezes dou esses graves…rsss… (ja editado)… muita coisa na cabeça e as vezes escrevo errado e não reviso o que escrevi… mais enfim… a questão do português deixa pra banca de concurso (mesmo assim agradeço pelo toque pois passou batido)…

vou pesquisar sobre o Process…

vlw…

[quote=entanglement]Esta é a primeira vez que vejo a palavra “terião”. Lembra um nome de comida japonesa.

De qualquer forma, é relativamente simples você usar expressões regulares para máscaras de arquivos. Basta lembrar que o equivalente do “" de máscaras de arquivos é a expressão regular ".”, o equivalente do “.” para máscaras de arquivos é a expressão regular “\.” e o equivalente do “?” é a expressão regular “.”.

Além disso, os seguintes caracteres, que são relevantes para expressões regulares mas não o são para máscaras de arquivos, devem ser protegidos:

“^” --> “\^”
“|” --> “\|”
“(” --> “\(”
“)” --> “\)”
“[” --> “\[”
“]” --> “\]”
“\” --> “\\”
“$” --> “\$”
“+” --> “\+”

[/quote]

heheehe… foi um grave feio…

ate ai eu ja tenho visto… a questão de “escapar” os caracteres e de dar o replace nos 3 que falei…
porém o que quero é… na expressão é possível se manter algo dinamico ?
ou tenho que ler o nome do arquivo a ser procurado… pesquisar e trocar caractere por caractere pra tornar essa expressão “dinamica” ?
não sei se to conseguindo ser claro o bastante…

mas qual seria sua dúvida?

se o usuário escrever algo com ?, vc pode dar um replace por isto . (ponto) que representa qualquer caractere

se for * ai vc precisa saber se é no começo ou no fim ok? ^inicio

Não entendo nada de expressão regular (infelizmente, mas pretendo estudar o assunto).

Segue um exemplo do Process public static void dir() { try { String line; Process p = Runtime.getRuntime().exec("cmd.exe /C dir"); BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (Exception err) { err.printStackTrace(); } finally { System.out.println("terminou o dir"); } }

o problema disso é que seu aplicativo vai depender do SO

Não necessariamente. O Java possui uma propriedade chamada os.name, que diz o nome do sistema operacional em uso. Essa propriedade é acessível através da seguinte chamada:

System.getProperty("os.name")

Se for linux, essa função retorna a String Linux; se for Windows, ela vai retornar Windows + alguma coisa, dependo da versão do windows.
De posse dessas informações, o método de execução do processo pode ser adaptado para:

String OS, command = ""; OS = System.getProperty("os.name"); if(OS.startsWith("Windows")) command = "cmd.exe /C "; else if (OS.equals("Linux")) command = "/bin/sh -c "; Process process = Runtime.getRuntime().exec(command + "Processo"); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (Exception err) { err.printStackTrace(); } finally { System.out.println("terminou o dir"); }

Valeu galera… me atribuíram outra coisa aqui por isso assim que retornar a essa atividade vou tentar as dicas da galera e posto os resultados… abraços

import java.io.File;
import java.io.FileFilter;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;

class ListarArquivosRecursivamente {

	private static Pattern adaptarWildcard (String wildcard) {
		// Os seguintes caracteres devem ser escapados em um wildcard, porque são significativos
		// para expressões regulares:
		// ^ | ( ) [ ] \ $ +
		// * equivale a .*, . equivale a \\., e ? equivale a .
		// Para simplificar, não vou levar em conta o caso .* , que equivale a .*.
		StringBuilder sb = new StringBuilder();
		for (char ch : wildcard.toCharArray()) {
			switch (ch) {
				case '^': case '|': case '(': case ')': case '[': case ']': case '\\': case '$': case '+': case '.':
					sb.append ('\\').append (ch); break;
				case '*': 
					sb.append (".*"); break;
				case '?':
					sb.append ('.'); break;
				default:
					sb.append (ch); break;
			}
		}
		return Pattern.compile (sb.toString(), Pattern.CASE_INSENSITIVE);
	}

	/**
	 * @param diretorio O diretorio (exemplo: "c:\\windows\\fonts")
	 * @param wildcard O padrao (exemplo: "*.ttf")
	 */
	public List<File> listar (String diretorio, String wildcard) {
		final Pattern pat = adaptarWildcard (wildcard);
		File[] arquivos = new File (diretorio).listFiles(new FileFilter() {
			public boolean accept (File pathname) {
				return pat.matcher(pathname.getName()).matches();
			}
		});
		if (arquivos == null) arquivos = new File[0];
		return Arrays.asList (arquivos);
	}

	/**
	 * @param diretorio O diretorio (exemplo: "c:\\windows\\fonts")
	 * @param wildcard O padrao (exemplo: "*.ttf")
	 */
	public List<File> listarRecursivamente (String diretorio, String wildcard) {
		final Pattern pat = adaptarWildcard (wildcard);
		List<File> files = new ArrayList<File>();
		listarRecursivamente (pat, new File (diretorio), files);
		return files;
	}
	
	private void listarRecursivamente (final Pattern pat, File diretorio, List<File> files) {
		File[] arquivosOuDiretorios = diretorio.listFiles (new FileFilter() {
			public boolean accept (File pathname) {
				return pathname.isDirectory() || pat.matcher (pathname.getName()).matches();
			}
		});
		for (File arquivoOuDiretorio : arquivosOuDiretorios) {
			if (arquivoOuDiretorio.isDirectory()) {
				listarRecursivamente (pat, arquivoOuDiretorio, files);
			} else {
				files.add (arquivoOuDiretorio);
			}
		}
	}
	
    public static void main (String[] args) {
		ListarArquivosRecursivamente lar = new ListarArquivosRecursivamente ();
		System.out.println ("------- Lista de arquivos do diretorio ----------");
		List<File> arquivos = lar.listar (args[0], args[1]);
		for (File arquivo: arquivos) {
			System.out.println (arquivo);
		}
		System.out.println ("------- Lista recursiva de arquivos do diretorio ----------");
		arquivos = lar.listarRecursivamente (args[0], args[1]);
		for (File arquivo: arquivos) {
			System.out.println (arquivo);
		}
	}
}

Exemplo:
java -cp . ListarRecursivamente “.” “*.java”

Note que usar simplesmente .java (e não ".java") dá resultados estranhos, tanto no Windows quanto no Linux e Unix, porque o Linux e Unix expandem esse “*.java” antes de passarem para o programa Java, e o Windows não expande automaticamente, mas o java.exe faz a expansão automática para você.

[quote=entanglement][code]
import java.io.File;
import java.io.FileFilter;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;

class ListarArquivosRecursivamente {

private static Pattern adaptarWildcard (String wildcard) {
	// Os seguintes caracteres devem ser escapados em um wildcard, porque são significativos
	// para expressões regulares:
	// ^ | ( ) [ ] \ $ +
	// * equivale a .*, . equivale a \\., e ? equivale a .
	// Para simplificar, não vou levar em conta o caso .* , que equivale a .*.
	StringBuilder sb = new StringBuilder();
	for (char ch : wildcard.toCharArray()) {
		switch (ch) {
			case '^': case '|': case '(': case ')': case '[': case ']': case '\\': case '$': case '+': case '.':
				sb.append ('\\').append (ch); break;
			case '*': 
				sb.append (".*"); break;
			case '?':
				sb.append ('.'); break;
			default:
				sb.append (ch); break;
		}
	}
	return Pattern.compile (sb.toString(), Pattern.CASE_INSENSITIVE);
}

/**
 * @param diretorio O diretorio (exemplo: "c:\\windows\\fonts")
 * @param wildcard O padrao (exemplo: "*.ttf")
 */
public List<File> listar (String diretorio, String wildcard) {
	final Pattern pat = adaptarWildcard (wildcard);
	File[] arquivos = new File (diretorio).listFiles(new FileFilter() {
		public boolean accept (File pathname) {
			return pat.matcher(pathname.getName()).matches();
		}
	});
	if (arquivos == null) arquivos = new File[0];
	return Arrays.asList (arquivos);
}

/**
 * @param diretorio O diretorio (exemplo: "c:\\windows\\fonts")
 * @param wildcard O padrao (exemplo: "*.ttf")
 */
public List<File> listarRecursivamente (String diretorio, String wildcard) {
	final Pattern pat = adaptarWildcard (wildcard);
	List<File> files = new ArrayList<File>();
	listarRecursivamente (pat, new File (diretorio), files);
	return files;
}

private void listarRecursivamente (final Pattern pat, File diretorio, List<File> files) {
	File[] arquivosOuDiretorios = diretorio.listFiles (new FileFilter() {
		public boolean accept (File pathname) {
			return pathname.isDirectory() || pat.matcher (pathname.getName()).matches();
		}
	});
	for (File arquivoOuDiretorio : arquivosOuDiretorios) {
		if (arquivoOuDiretorio.isDirectory()) {
			listarRecursivamente (pat, arquivoOuDiretorio, files);
		} else {
			files.add (arquivoOuDiretorio);
		}
	}
}

public static void main (String[] args) {
	ListarArquivosRecursivamente lar = new ListarArquivosRecursivamente ();
	System.out.println ("------- Lista de arquivos do diretorio ----------");
	List<File> arquivos = lar.listar (args[0], args[1]);
	for (File arquivo: arquivos) {
		System.out.println (arquivo);
	}
	System.out.println ("------- Lista recursiva de arquivos do diretorio ----------");
	arquivos = lar.listarRecursivamente (args[0], args[1]);
	for (File arquivo: arquivos) {
		System.out.println (arquivo);
	}
}

}
[/code]

Exemplo:
java -cp . ListarRecursivamente “.” “*.java”

Note que usar simplesmente .java (e não ".java") dá resultados estranhos, tanto no Windows quanto no Linux e Unix, porque o Linux e Unix expandem esse “*.java” antes de passarem para o programa Java, e o Windows não expande automaticamente, mas o java.exe faz a expansão automática para você.
[/quote]

entanglement … é exatamente isso que eu precisava… implementei com o codigo que eu tinha e funcionou certinho…
só aguardar a homologação… mais acredito que sera finalizado nisso ai…

valeu a força…
abraços