webForumDet fria alternativet

Regular Expressions till validering?

19 svar · 619 visningar · startad av PersianBulldog

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#1

Hejsan,

Jag har börjat läst lite om Regex men fått intrycket av att det enbart kan användas för manipulering och redigering av strängar.

Går det att t.e.x kolla om en sträng innehåller ett giltligt filnamn (sett till filändelse och punktering) exempelvis att filnamn != .txt inte accepteras? Hur skulle det då se ut? För tillfället har jag en riktigt ful lösning som bygger på length()-4, indexOf() etc.

Jag har aldrig använt reguljära uttryck men får intryck av att det skulle vara en otrolig förbättring, sett till optimering, att börja göra det.

Förresten, detta är den enda officiella information jag hittade om ämnet i fråga (iofs har jag inte letat allt för hårt eller läst igenom texten på den länkade sidan) och därför undrar jag om någon har något mer att bidra?

Tack på förhand.

spangoMedlem sedan juni 20006 147 inlägg
#2

Regexpar kan användas för att manipulera och matcha strängar. Man måste sitta och trixa lite med regexpar för att man ska lära sig använda dem, men manualsidan för Pattern är rätt instruktiv: http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html

En lösning på ditt exempel skulle kunna vara typ:

String pattern = "[a-zA-Z0-9_\\-]+" // börja med minst en bokstav, undersläng, bindestreck eller siffra
   + "\\." // följt av en punkt
   + "[a-zA-Z]{3}"; // följt av tre bokstäver
String filename = ...;
if (Pattern.matches(pattern, filename))
   playThatFunkyMusic();
PersianBulldogMedlem sedan aug. 20022 380 inlägg
#3
			System.out.print("Mata in filnamnet på den textfil vars rader du vill räkna: ");
			fileName=indata.readLine();
			
			String myPattern = "[a-zA-Z0-9_\\-]+" + "\\." + "[a-zA-Z]{3}";
			
				if (Pattern.matches(myPattern, fileName)){
					System.out.println("Det är ett filnamn");}

ger

spango.java:374: cannot resolve symbol
symbol  : variable Pattern 
location: class spango
				if (Pattern.matches(myPattern, fileName)){
spangoMedlem sedan juni 20006 147 inlägg
#4

import java.util.regex.Pattern;

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#5

import java.util.*;

har jag redan. :(

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#6
import java.io.*; 
import java.util.*;
import javax.swing.*;

	public static void main (String[]arg) throws IOException{

		String menuChoice =null;
		String fileName = null;
		
	System.out.println("\n\n\n\n\n\n\n\n\n");	
       			BufferedReader indata = new BufferedReader(new InputStreamReader(System.in));	
	System.out.print  ("\n\tDitt menyval: ");
		
		
		
		menuChoice = indata.readLine();
		
		if(menuChoice.equals("1")){
			System.out.println("\nDu vill jämföra");}
			
		if(menuChoice.equals("2")){
			System.out.print("Mata in filnamnet på den textfil vars rader du vill räkna: ");
			fileName=indata.readLine();
			
			String regex = "[a-zA-Z0-9_\\-]+" + "\\." + "[a-zA-Z]{3}";
			
				if (Pattern.matches(regex, fileName)){
					System.out.println("Det är ett filnamn");}
					
				System.out.println("Det är inte ett filnamn");
			
			
			
			
		if(menuChoice.equals("3")){
			System.out.println("\nDu vill kopiera");}
			
		if(menuChoice.equals("4")){
			System.out.println("\nDu vill söka");}
				
					System.exit(1337);
			
		}
		
	}
antilizaerMedlem sedan apr. 200358 inlägg
#7

java.util.regex.* och java.util.* är två olika paket så du måste importera båda:

import java.io.*; 
import java.util.*;
import java.util.regex.*;
import javax.swing.*;
...
PersianBulldogMedlem sedan aug. 20022 380 inlägg
#8

Men hur kan det vara så? Borde inte asterisken täcka allt underliggande?

Ett stort tack till spango och antilizaer!

spangoMedlem sedan juni 20006 147 inlägg
#9

Nix, wildcard inkluderar bara klasserna i ett paket, inte underpaketen. Gjorde den det skulle risken för namnkrockar öka betydligt samtidigt som omaket skulle minska ytterst marginellt.

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#10

I see,

kan du ge exempel på en klass och ett underpaket i t.ex. util paketet? Jag har inte riktigt greppat alla namn. Hur ser man skillnaden på dessa i SDKn?

spangoMedlem sedan juni 20006 147 inlägg
#11

java.util är ett paket som innehåller bl.a. de olika Collection-klasserna, ArrayList, HashSet & c:o. Teoretiskt sett kan man säga att java.util är ett underpaket till paketet java (även om det inte finns några klasser som ligger i just paketet java) eftersom paket har namn på formen "huvudpaket.underpaket1.underpaket2.ochsåvidare". Hursomhelst är java.util.regex ett underpaket till java.util, och java.util.regex innehåller lite klasser för regexpar.

Om du kikar på API-dokumentationen har du en lista på alla paket i Java 5, Standard Edition uppe till vänster, och när du klickar på ett paket får du upp listan över vilka klasser och interface det paketet innehåller i framen under. Paket används som bekant för att organisera klasser i en lätthanterlig katalogliknande struktur, så har man en bunt klasser som hör ihop bör de ligga i ett eget paket. (Med den logiken borde de olika Collection-klasserna haft ett eget paket i stil med java.util.collections eller liknande, men så blev det inte...)

Underpaket fyller ingen egentlig funktion bortsett från att man då kan organisera saker och ting i just katalogstruktur. Man hade, utan att mista någon funktionalitet, kunnat ha allt i "toppnivåpaket", men det hade blivit grötigt.

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#12

Det var ett utmärkt svar, spango. :)

java.util - Paket
java.util.regex - Underpaket till ovanstående
Pattern - Exempel på klass i ovanstående underpaket

java.lang.Object
      |_ java.util.regex.Pattern

Vad är java.lang.Object då i detta fall?

Vad är interfaces? Exceptions är väl ett fel som kan uppstå vid användning av klassen? Eller är det vid användning av en viss metod?

missModestyMedlem sedan apr. 2005228 inlägg
#13

Jag gör ett försök att svara. Kan någon bättre så är det bara att fylla på eller rätta mig.

Object är en klass i java.lang som ger den grundläggande koden som alla javaobjekt måste ha. Faktum är att till alla klasser som inte redan är en utvidgnig av en annan klass lägger kompilatorn automatiskt till "extends Object". Man kan se Object som botten i klass-hierarkin.

Interface kan man använda sig av för att definiera knutpunkter mellan klasser. Om du och jag ska skriva en varsin klass som har vissa knutpunkter är det bra att ha ett interface som garanterar att de passar ihop sen. När jag sedan skriver min klass så vet jag att de metoder jag behöver kommer att finnas i din klass eftersom den uppfyller det gränssnitt/interface vi kommit överens om innan.

Exceptions kastas i körtid när programmet får fel indata och det blir omöjligt att gå vidare.

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#14

Tack för förklaringen, missModesty. Jag tror jag nästan förstår. :D

missModestyMedlem sedan apr. 2005228 inlägg
#15

Kan väl nämna skillnaden mellan ett interface och en abstrakt klass så kanske poletten trillar ned.

Om du har tex. public class Bla implements BlaBla så garanteras att Bla bland sina metoder har de som BlaBla lovar genom gränssnittet

Medan om du har public class Bla extends Blob så ärver Bla existerande kod från Blob och lägger till egen kod.

PersianBulldogMedlem sedan aug. 20022 380 inlägg
#16

Nu börjar det nästan bli lite överkurs. ;)

Men det där med extends och implements är alltså class resp. interface-specifika kommandon (säger man så?)?

missModestyMedlem sedan apr. 2005228 inlägg
#17

Det var nog dumt av mig att ta upp skillnaden mellan ett interface och en abstrakt klass. Jag gjorde det för att en del har svårt att förstå skillnaden ibörjan.

När det gäller hur man säger så är jag usel på terminologi.

Kortfattat och förenklat så använder du extends när du bygger vidare på en redan existerande klass som du vill ärva metoder av och implements till gränssnitt som anger metoder som ska vara med utan att ha implementerat dem.

DufferMedlem sedan mars 2003409 inlägg
#18

Ny fråga!

Hej
till String finns metoden replaceAll()

med denna kan man ha ett regulärt uttryck och en sträng som inparameter, men jag tror inte riktigt att jag lyckas med mitt uttryck :(

vill skriva ett uttryck som bland annat ersätter alla bokstäver, till detta fattade jag det som att \D skulle räcka
(\D = A non-digit: [^0-9])

men skriver jag replaceAll("\D", "ny sträng"); då får jag felet:
illegal escape character

å andra sidan använder jag \t (tabb) så kan jag kompilera men tro inte att tab ersätts =(

LimeMedlem sedan sep. 2001837 inlägg
#19

Helt korret. Det är \D som är "all non digits" i regexp.

Och tecknet \ är escape-tecken i strängar i java.

Så för att få \D som sträng måste man skriva "\\D"

DufferMedlem sedan mars 2003409 inlägg
#20

:r tack så mycket! :birp

Genererad på 394 ms · cache AV · v20260730165559-full.f96bc7eb