ID:170522
 
How would I search for text in a string and replace it with other text. What I want to do is make hub://Sgeo.build type URLs work.
Sgeo wrote:
How would I search for text in a string and replace it with other text. What I want to do is make hub://Sgeo.build type URLs work.

A free-for-all snippet I wrote a while ago:
[edit] (Be careful using it on huge strings though)
[edit 2] Yes, it was a while ago. It is optimized now.

proc/stringreplace(string, find, replace)
var/pos = findtext(string, find)
if(pos == 0)
return string
else
return copytext(string,1,pos) + replace + stringreplace(copytext(string,pos+length(find),0), find, replace)

In response to Gazoot
How come, when you try to search through large lists, it crashes DS? I wanna do something with my project, but it involves searching through long lists to replace things.
Sgeo wrote:
How would I search for text in a string and replace it with other text. What I want to do is make hub://Sgeo.build type URLs work.

Ok, using my updated stringreplace(), this should work:

var/pos = findtext(string, "hub://")
if(pos)
var/space = findtext(string, " ", pos)
var/text = copytext(string, pos+6, space)
string = stringreplace(string, "hub://[text]", "<a href='http://www.byond.com/hub/[text]'>hub://[text]</a>")


[edit] Yes it is 3:40am and it was broken before!
In response to Artekia
Artekia wrote:
How come, when you try to search through large lists, it crashes DS? I wanna do something with my project, but it involves searching through long lists to replace things.

It's a recursive function, so if the strings are huge it will run out of memory. But why it's related to lists, I don't know. Does it crash even with the updated version? Post some code if you want, I'll take a look!


/Gazoot
In response to Gazoot
Bah, I don't really know what I'm doing.. this whole replacing text stuff really confuses me. I tried to make it search through the string to find letters and replace them with other letters but with the updated version I couldn't really figure out how to do it. I just don't understand how replacement procs work really.
In response to Artekia
Check out Unknown Person's l33t2text library.
In response to Hell Ramen
Is there a way to replace things all at once or something so that if I replaced "A" with "B" it wouldn't replace that "B" with "C", for example.
In response to Gazoot
Gazoot, instead of if(pos==0), you should have if(!pos) there =P.
I've taken Gazoot's proc and made a little demo for you:

proc

stringreplace(string,find,replace)//Gazoot

var/pos = findtext(string, find)

if(!pos)
return string

else
return copytext(string,1,pos) + replace + stringreplace(copytext(string,pos+length(find),0), find, replace)

hubparse(string as text,word="hub://")

var/pos = findtext(string, word)

if(pos)

var
space = findtext(string, " ", pos)//It ends the hyperlink right before the space that way
text = copytext(string, pos+length(word), space)

string = stringreplace(string, "[word][text]", "<a href='http://www.byond.com/hub/[text]'>[word][text]</a>")

return string

mob/verb/Say(T as text)
world << "[hubparse(T)]"


[edit]1/15/04: Fixed full_stringreplace(). Before, it crashed the program (length(string) was changing, of course, as the string was replaced).

[edit]1/19/04: Realized that there was no need for full_stringreplace().
In response to Wizkidd0123
Wizkidd0123 wrote:
Gazoot, instead of if(pos==0), you should have if(!pos) there =P.

Nah, I wanted to be strict about the returned type. A habit from the string search in PHP, where the first position of the found string could be 0, which is considered the same as null if you do loose typing. (It's one of those occasions where you need to use the peculiar "===" operator)

Of course in Byond it doesn't matter because the first pos is returned as 1, but I wanted to be consistent. :P


/Gazoot
In response to Artekia
Artekia wrote:
Is there a way to replace things all at once or something so that if I replaced "A" with "B" it wouldn't replace that "B" with "C", for example.

Can you explain a bit more what you're trying to do? Doing what you want takes some modifications to the stringreplace function, but maybe there is another way of doing it...?


/Gazoot
In response to Gazoot
Like if I had a list of words I wanted to replace like this
var/list/ReplaceThese=list("A","B")
var/list/Replacements=list("B","E")

If I used a replacement proc and put in "A" it'd return "E", since it replaces "A" with "B" and than it does it again and replaces that "B" with "E".
In response to Artekia
Artekia wrote:
If I used a replacement proc and put in "A" it'd return "E", since it replaces "A" with "B" and than it does it again and replaces that "B" with "E".

Yes I understand that concept, but it was a quite special request, so maybe the whole thing that you're doing could be done in another way? I just got that feeling.

Anyway, to do it you need an exception list. Add the searched characters to the list, then check before replacing if the searched char is in that list.


/Gazoot
In response to Gazoot
I thought that something like that might've been what was needed, but I have no clue how to implement it.. well thanks anyway.