webForumDet fria alternativet

Regular Expression

Java

5 svar · 520 visningar · startad av Viktor

Medlem sedan aug. 20021 752 inlägg
Frågan#1

Jag behöver lite hjälp med regular expressions.
Jag vill göra om denna text sträng,

[ URL]http://www.webforum.com/

till

<a href="http://www.webforum.com/">http://www.webforum.com/\</a>

och

[ URL=http://www.webforum.com/\]webForum

till

<a href="http://www.webforum.com/">webForum</a>

dvs precis som taggen fungerar här på forumet :)

Jag har lyckats göra detta men det är ingen snygg lösning och nu undrar jag om det finns någon som vet hur mna kan göra det bättre, kankse bara med regular expressions

// Create a pattern to match cat
Pattern p = Pattern.compile("\\[url\\](.*?)\\[/url\\]",Pattern.CASE_INSENSITIVE);
// Create a matcher with an input string
Matcher m = p.matcher("one cat," + " [ url]http://www.microsoft.com/[/UrL] cats in the yard");
StringBuffer sb = new StringBuffer();
boolean result = m.find();
// Loop through and create a new String
// with the replacements
while(result)
{
	String s=m.group();
	s=s.substring(5,s.length()-6);
	m.appendReplacement(sb, "<a href=\""+s+"\" target=\"_new\">"+s+"</a>");
	result = m.find();
}
// Add the last segment of input to
// the new String
m.appendTail(sb);
System.out.println(sb.toString());

och här är koden för den andra typen av länkar

// Create a pattern to match cat
Pattern p = Pattern.compile("\\[url=(.*?)\\](.*?)\\[/url\\]",Pattern.CASE_INSENSITIVE);
// Create a matcher with an input string
Matcher m = p.matcher("one cat," + " [url=http://www.microsoft.com/]Microsoft[/UrL] cats in the yard");
StringBuffer sb = new StringBuffer();
boolean result = m.find();
// Loop through and create a new String
// with the replacements
while(result)
{
	String s=m.group();
	String u="";
	s=s.substring(5);
	u=s.substring(0,s.indexOf("]"));
	s=s.substring(s.indexOf("]")+1,s.length()-6);
	m.appendReplacement(sb, "<a href=\""+u+"\" target=\"_new\">"+s+"</a>");
	result = m.find();
}
// Add the last segment of input to
// the new String
m.appendTail(sb);
System.out.println(sb.toString());

Eller är det såhär man ska göra? Har aldrig jobbat med regular expressions förut :)

/Viktor

Medlem sedan aug. 20021 752 inlägg
#2

Nu är allt ovan löst (nästan), men nu har jag en till fråga.

Hur kan jag göra så att en regexp sökning söker på flera rader? Som det är nu måste både start och slut taggen finnas på samma rad men jag skulle vilja att den kan hitta även om de inte finns på samma rad.
Såhär ser mitt regexp för bold taggen ut,

\[b\](.*?)\[/b\]

denna fungerar bra om det ser ut såhär (utan space)

[b ]Hej Hopp[/b]

men inte om det står

[b ]Hej
Hopp[/b]

jag vet att "." betyder allt utom rad brytning, men vad ska jag byta det mot?

/Viktor

Medlem sedan mars 20007 896 inlägg
#3

Du skickar ju två parameter till Pattern.compile(), dvs. mönstret och sen en flagga som visar hur den ska läsa av mönstret. Du använder nu CASE_INSENSITIVE, men du kan också använda MULTILINE för att det ska gälla över flera rader.

Pattern.compile( "a*b", MULTILINE );

Tror att det ska lösa biffen.

Medlem sedan aug. 20021 752 inlägg
#4

Det hjälpte inte men jag hittade "DOTALL" och den fungerade. Men nu har jag ett annat problem när jag kör med det men det ska jag försöka lösa själv :)

/Viktor

Medlem sedan juni 200010 432 inlägg
#5

Jag har lyckats göra detta men det är ingen snygg lösning

Visserligen är din lösning inte "snygg", men frågan är ändå om den inte är effektivare än reguljära uttryck, med avseende på tidskomplexitet. Har man endast lite som ska utföras är det i regel snabbare att göra detta "direkt" med en egen algoritm eftersom regexpar tenderar att vara "tunga" ;)

Medlem sedan aug. 20021 752 inlägg
#6

Det här är slutresultatet,

public synchronized String Replace(String text, String find, String replace, boolean CASE_SENSITIVE)
{
	Pattern p;
	int i;
	String tmp="";
	if(CASE_SENSITIVE)
		p=Pattern.compile(find,Pattern.DOTALL);
	else
		p=Pattern.compile(find,Pattern.DOTALL|Pattern.CASE_INSENSITIVE);
	Matcher m=p.matcher(text);
	StringBuffer sb=new StringBuffer();
	boolean result=m.find();
	while(result)
	{
		tmp=replace;
		for(i=1;i<m.groupCount()+1;i++)
			tmp=tmp.replaceAll("bb-"+i,m.group(i));
		m.appendReplacement(sb,tmp);
		result = m.find();
	};
	m.appendTail(sb);
	return(sb.toString());
}

En generell funktion som tar in en text, vad som ska sökas efter och vad som ska skrivas istället för det som hittas. Fungerar perfekt, klarar av alla taggar som det här forumet klarar av :)
En lite fråga dock, kan man skriva "Pattern.DOTALL|Pattern.CASE_INSENSITIVE"? Jag vet att man gör så i C++ men har aldrig tänkt på hur man gör i Java, det verkar fungera bra men det kanske bara är slumpen :)

/Viktor

263 ms totalt · 3 externa anrop · v20260731065814-full.767b4345
122 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)