问题
I have the next string:
countries_united_states_ohio
sometimes it can be countries_spain_madrid
How can I remove the word Countries and have the next output:United States, Ohio
orSpain, Madrid
I'm using Smarty and I tried something like this:
{$string|replace:"_":", "|capitalize}
The problem is that it returns United,States(as expected) and I guess I could remove the word 'countries' using substr.
Anyone has any idea?
Thank you!
回答1:
I think I found a way.
You will need a list of all countries in the world. Example: https://www.countries-ofthe-world.com/all-countries.html
The code will look at each part of the string and see if it's a "country word" if true:
It will make sure it has not already grabbed that word (see all "uinited" countries).
If it is not already in the country array then add it there.
Now I can just implode the country.
State/city is what is left of I remove country and _
.
$Ucountries = ["Uganda",
"Ukraine",
"United Arab Emirates (UAE)",
"United Kingdom (UK)",
"United States of America (USA)",
"Uruguay",
"Uzbekistan"];
$Mcountries = ["Macedonia (FYROM)",
"Madagascar",
"Malawi",
"Malaysia",
"Maldives",
"Mali",
"Malta",
"Marshall Islands",
"Mauritania",
"Mauritius",
"Mexico",
"Micronesia",
"Moldova",
"Monaco",
"Mongolia",
"Montenegro",
"Morocco",
"Mozambique",
"Myanmar (Burma)"];
$str = "countries_mexico_mexico_city";
//$str = "countries_united_states_ohio";
$str = str_replace("countries_", "", $str);
// Copy array needed to $CountryList
$CountryList = ${strtoupper(substr($str,0,1)). "countries"};
$countryarr = array();
$arr = explode("_", $str);
Foreach($arr as $val){
Foreach($CountryList as $item){
If(stripos($item, $val) !== false){
If(!in_array($val, $countryarr)){
$countryarr[] = $val;
}
}
}
}
$country = implode(" ", $countryarr);
$state_city = preg_replace("/" . implode("_",$countryarr) . "/", "", $str,1);
$state_city = trim(str_replace("_", " ", $state_city));
Echo $country . "\n" . $state_city;
https://3v4l.org/POMPT
Edit; thought of a way when I was brushing my teeth.
Since the countryarr will only have Mexico I can with preg_replace replace only once.
Also I had to change the replace pattern to a implode of countryarr.
Now what is left is a state/city with a underscore first and one or more words separated with underscore.
So replace underscore with space and trim the string.
EDIT2; Now that I have had some sleep I thought that the array to match against countries will be very large.
So I made a change.
Each first letter of country is a new array, and the code will only loop in the countries with the same first letter.
回答2:
Use explode to split it on _
$textString = "countries_united_states_ohio";
$split = explode("_",$textString);
$split will now be
$split = [countries,united,states,ohio];
Then you can do with it what you wish, $split[#] for a position, re-assemble, etc.
countries_spain_madrid
echo $split[1].",".$split[2];
outputting => spain, madrid
countries_united_states_ohio
echo $split[1]." ".$split[2].",".$split[3];
outputting => united states, ohio
But the issue here is that the way you have it set, there's no efficient programmatic way to determine if it is a space or a delimiter to split the words (i.e. united_states or countries_span_madrid).
If you know what's going in you can figure it out like that but it's still not very efficient and it means you basically statically doing it or determining specific words it in that signify it to be a group of words for ONE word (united states) or single world
You could try using a different separator for spaces vs word splits. Maybe _ for space and - for split. Like say united_states-ohio
回答3:
If countries_
is always at the beginning, removing that will be easy enough, and it sounds like you already know how to do that.
But I don't think splitting up the rest of the string properly will be possible using only string functions, in Smarty or PHP in general. The problem is, you need a different delimiter between terms if underscore is also going to be used to separate the words in terms that have multiple words, like "united states". There's no way for the code to know whether each underscore indicates a term delimiter or a space within a single term.
You might be able to accomplish it if you compare the input string to a list of possible terms (countries, states, cities, etc.) that could be included, but it will be much more complex than just a string replacement. Hopefully you are able to modify how these strings are stored or generated so that they'll use a different delimiter.
来源:https://stackoverflow.com/questions/45741810/smarty-php-regex-replace