Replace Variables in String?
Unless I'm missing something, can't you use the string.replace function?
You could do something like:
foreach (var tag in ArrayNode)
{
Comp = Comp.Replace(tag.TagPointer, tag.TagValue);
}
myString.replace( VARIABLE, ) ...... but globally
Well, you can use this:
var reg = new RegExp(oldWord, "g");
myString.replace(reg, "");
or simply:
myString.replace(new RegExp(oldWord, "g"), "");
C# How to replace the variables inside strings
You can try to Replace
all {...}
with a help of Regular Expressions:
using System.Text.RegularExpressions;
...
// All possible substitutions (from database?)
Dictionary<string, string> replacements =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
{ "name", "name1"},
{ "country", "country1"},
};
string greet = "Hi {name}, Are you from {country}";
string result = Regex.Replace(
greet,
@"(?<=\{).*?(?=\})",
match => replacements.TryGetValue(match.Value, out var value) ? value : "???");
Replace one substring for another string in shell script
To replace the first occurrence of a pattern with a given string, use ${parameter/pattern/string}
:
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/"$secondString"}"
# prints 'I love Sara and Marry'
To replace all occurrences, use ${parameter//pattern/string}
:
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(This is documented in the Bash Reference Manual, §3.5.3 "Shell Parameter Expansion".)
Note that this feature is not specified by POSIX — it's a Bash extension — so not all Unix shells implement it. For the relevant POSIX documentation, see The Open Group Technical Standard Base Specifications, Issue 7, the Shell & Utilities volume, §2.6.2 "Parameter Expansion".
Replacing variables in a string
I'm going to add an answer here because none of the current answers really cut the mustard in my view. I'll dive straight in and show you the code I would use to do this:
function parse(
/* string */ $subject,
array $variables,
/* string */ $escapeChar = '@',
/* string */ $errPlaceholder = null
) {
$esc = preg_quote($escapeChar);
$expr = "/
$esc$esc(?=$esc*+{)
| $esc{
| {(\w+)}
/x";
$callback = function($match) use($variables, $escapeChar, $errPlaceholder) {
switch ($match[0]) {
case $escapeChar . $escapeChar:
return $escapeChar;
case $escapeChar . '{':
return '{';
default:
if (isset($variables[$match[1]])) {
return $variables[$match[1]];
}
return isset($errPlaceholder) ? $errPlaceholder : $match[0];
}
};
return preg_replace_callback($expr, $callback, $subject);
}
What does that do?
In a nutshell:
- Create a regular expression using the specified escape character that will match one of three sequences (more on that below)
- Feed that into
preg_replace_callback()
, where the callback handles two of those sequences exactly and treats everything else as a replacement operation. - Return the resulting string
The regex
The regex matches any one of these three sequences:
- Two occurrences of the escape character, followed by zero or more occurrences of the escape character, followed by an opening curly brace. Only the first two occurrences of the escape character are consumed. This is replaced by a single occurrence of the escape character.
- A single occurrence of the escape character followed by an opening curly brace. This is replaced by a literal open curly brace.
- An opening curly brace, followed by one or more perl word characters (alpha-numerics and the underscore character) followed by a closing curly brace. This is treated as a placeholder and a lookup is performed for the name between the braces in the
$variables
array, if it is found then return the replacement value, if not then return the value of$errPlaceholder
- by default this isnull
, which is treated as a special case and the original placeholder is returned (i.e. the string is not modified).
Why is it better?
To understand why it's better, let's look at the replacement approaches take by other answers. With one exception (the only failing of which is compatibility with PHP<5.4 and slightly non-obvious behaviour), these fall into two categories:
strtr()
- This provides no mechanism for handling an escape character. What if your input string needs a literal{X}
in it?strtr()
does not account for this, and it would be substituted for the value$X
.str_replace()
- this suffers from the same issue asstrtr()
, and another problem as well. When you callstr_replace()
with an array argument for the search/replace arguments, it behaves as if you had called it multiple times - one for each of the array of replacement pairs. This means that if one of your replacement strings contains a value that appears later in the search array, you will end up substituting that as well.
To demonstrate this issue with str_replace()
, consider the following code:
$pairs = array('A' => 'B', 'B' => 'C');
echo str_replace(array_keys($pairs), array_values($pairs), 'AB');
Now, you'd probably expect the output here to be BC
but it will actually be CC
(demo) - this is because the first iteration replaced A
with B
, and in the second iteration the subject string was BB
- so both of these occurrences of B
were replaced with C
.
This issue also betrays a performance consideration that might not be immediately obvious - because each pair is handled separately, the operation is O(n)
, for each replacement pair the entire string is searched and the single replacement operation handled. If you had a very large subject string and a lot of replacement pairs, that's a sizeable operation going on under the bonnet.
Arguably this performance consideration is a non-issue - you would need a very large string and a lot of replacement pairs before you got a meaningful slowdown, but it's still worth remembering. It's also worth remembering that regex has performance penalties of its own, so in general this consideration shouldn't be included in the decision-making process.
Instead we use preg_replace_callback()
. This visits any given part of the string looking for matches exactly once, within the bounds of the supplied regular expression. I add this qualifier because if you write an expression that causes catastrophic backtracking then it will be considerably more than once, but in this case that shouldn't be a problem (to help avoid this I made the only repetition in the expression possessive).
We use preg_replace_callback()
instead of preg_replace()
to allow us to apply custom logic while looking for the replacement string.
What this allows you to do
The original example from the question
$X = 'Dany';
$Y = 'Stack Overflow';
$lang['example'] = '{X} created a thread on {Y}';
echo parse($lang['example']);
This becomes:
$pairs = array(
'X' = 'Dany',
'Y' = 'Stack Overflow',
);
$lang['example'] = '{X} created a thread on {Y}';
echo parse($lang['example'], $pairs);
// Dany created a thread on Stack Overflow
Something more advanced
Now let's say we have:
$lang['example'] = '{X} created a thread on {Y} and it contained {X}';
// Dany created a thread on Stack Overflow and it contained Dany
...and we want the second {X}
to appear literally in the resulting string. Using the default escape character of @
, we would change it to:
$lang['example'] = '{X} created a thread on {Y} and it contained @{X}';
// Dany created a thread on Stack Overflow and it contained {X}
OK, looks good so far. But what if that @
was supposed to be a literal?
$lang['example'] = '{X} created a thread on {Y} and it contained @@{X}';
// Dany created a thread on Stack Overflow and it contained @Dany
Note that the regular expression has been designed to only pay attention to escape sequences that immediately precede an opening curly brace. This means that you don't need to escape the escape character unless it appears immediately in front of a placeholder.
A note about the use of an array as an argument
Your original code sample uses variables named the same way as the placeholders in the string. Mine uses an array with named keys. There are two very good reasons for this:
- Clarity and security - it's much easier to see what will end up being substituted, and you don't risk accidentally substituting variables you don't want to be exposed. It wouldn't be much good if someone could simply feed in
{dbPass}
and see your database password, now would it? - Scope - it's not possible to import variables from the calling scope unless the caller is the global scope. This makes the function useless if called from another function, and importing data from another scope is very bad practice.
If you really want to use named variables from the current scope (and I do not recommend this due to the aforementioned security issues) you can pass the result of a call to get_defined_vars()
to the second argument.
A note about choosing an escape character
You'll notice I chose @
as the default escape character. You can use any character (or sequence of characters, it can be more than one) by passing it to the third argument - and you may be tempted to use \
since that's what many languages use, but hold on before you do that.
The reason you don't want to use \
is because many languages use it as their own escape character, which means that when you want to specify your escape character in, say, a PHP string literal, you run into this problem:
$lang['example'] = '\\{X}'; // results in {X}
$lang['example'] = '\\\{X}'; // results in \Dany
$lang['example'] = '\\\\{X}'; // results in \Dany
It can lead to a readability nightmare, and some non-obvious behaviour with complex patterns. Pick an escape character that is not used by any other language involved (for example, if you are using this technique to generate fragments of HTML, don't use &
as an escape character either).
To sum up
What you are doing has edge-cases. To solve the problem properly, you need to use a tool capable of handling those edge-cases - and when it comes to string manipulation, the tool for the job is most often regex.
Replacing names of the variable with value of the variable in a String in Java
You can use a the java buildin regular expression mechanism to find the pattern in the inspected string and make the replacement using the proper functions. Let me show you...
public static void main(String[] args)
{
StringBuilder output = new StringBuilder();
String inputString = "sequence to analize #{var1} is like #{var2}";
Pattern pattern = Pattern.compile("#\\{(.*?)\\}");
Matcher matcher = pattern.matcher(inputString);
int lastStart = 0;
while (matcher.find()) {
String subString = inputString.substring(lastStart,matcher.start());
String varName = matcher.group(1);
String replacement = getVarValue (varName);
output.append(subString).append(replacement);
lastStart = matcher.end();
}
System.out.println(output.toString());
}
private static String getVarValue(String varName) {
return "value"; // do what you got to replace the variable name for its value
}
Perhaps the example needs to be worked a little more.. but it can give you an idea.
Hope it Helps.
Greetings.
Replace variables from a given string
GetType().GetProperty() only returns public properties, make your property public inorder for this to work (or you can use bindingFlags)
take a look at this :
https://learn.microsoft.com/en-us/dotnet/api/system.type.getproperty?view=net-5.0
Related Topics
MySQL Alter Table Add Field Before or After a Field Already Present
Execute a PHP Script from Another PHP Script
I Have a Base64 Encoded Png, How to Write the Image to a File in PHP
Codeigniter - File Upload Required Validation
Codeigniter Assets Folder Best Practice
How to Detect If Have to Apply Utf-8 Decode or Encode on a String
PHP Remove Elements from Associative Array
Removing Black Borders 4:3 on Youtube Thumbnails
Url Encode Equivalent in Ruby on Rails
Change Name of Laravel's Created_At and Updated_At
Php: Get List of All Filenames Contained Within My Images Directory
Move All Files in a Folder to Another
How to Create a New Joomla User Account from Within a Script
Differencebetween Null and Empty
Message: Trying to Access Array Offset on Value of Type Null