Regex for GString Token - regex

I have an ID in this format:
1.5.31.14.${CHANNEL}.${SLOT}
It's read in from a file as a string and I'm trying to replace ${} tokens with other variables.
However, when I run:
id.replaceAll("\${CHANNEL}", "3")
it will attempt to replace ${CHANNEL} with a value called
CHANNEL
within the function and throw an error.
I've been going crazy trying to figure out what RegEx I can use to replace
${CHANNEL} and ${SLOT}
in the ID.
If anybody has any suggestions, please let me know.
EDIT:
Here is the error:
Exception thrown
groovy.lang.MissingPropertyException: No such property: CARD for class: ConsoleScript91
EDIT 2
Here is the code I ran:
def id = '1.5.31.14.${CHANNEL}.${SLOT}'
id = id.replaceAll('\${CHANNEL}', '3')
replaced = id.replaceAll('\${SLOT}', '2')
print replaced
Here is the error:
Exception thrown
java.util.regex.PatternSyntaxException: Illegal repetition near index 0
${CHANNEL}
^
at java_lang_String$replaceAll$1.call(Unknown Source)
at ConsoleScript5.run(ConsoleScript5:2)

You need to escape both dollar sign $ and curly braces {}. Mind the fact that \ is a special character so it should be escaped itself:
def id = '1.5.31.14.${CHANNEL}.${SLOT}'
replaced = id.replaceAll('\\$\\{CHANNEL\\}', '3').replaceAll('\\$\\{SLOT\\}', '2')
replaced2 = id.replaceAll(/\$\{CHANNEL\}/, '3').replaceAll(/\$\{SLOT\}/, '2')
assert replaced == '1.5.31.14.3.2'
assert replaced == replaced2

Related

How to regex a branch name?

I have variable with "origin/blahbranch" that I want to substring into "blahbranch", how to substring it? I tried with
dev newbranch = (branch1 =~ /.*)[0]
but that left me with
1. / sign included which I don't want
2. the actual git instruction returns error message when embedding the parameter ${newbranch} :
"unexpected char: '''"
Assuming branch1 is string you can use split function
List<String> list = new ArrayList<String>(Arrays.asList(branch1.split("/")));
list.remove(0);
def newbranch = String.join("/", list.toArray(new String[0]))
println newbranch
Very simple solution considering remote always remains origin you can do below
def newbranch = "origin/blahbrachwithslash/blahbranch".replace("origin/","")
println newbranch

Replace variable names with actual class Properties - Regex? (C#)

I need to send a custom email message to every User of a list ( List < User > ) I have. (I'm using C# .NET)
What I would need to do is to replace all the expressions (that start with "[?&=" have "variableName" in the middle and then ends with "]") with the actual User property value.
So for example if I have a text like this:
"Hello, [?&=Name]. A gift will be sent to [?&=Address], [?&=Zipcode], [?&=Country].
If [?&=Email] is not your email address, please contact us."
I would like to get this for the user:
"Hello, Mary. A gift will be sent to Boulevard Spain 918, 11300, Uruguay.
If marytech#gmail.com is not your email address, please contact us."
Is there a practical and clean way to do this with Regex?
This is a good place to apply regex.
The regular expression you want looks like this /\[\?&=(\w*)\]/ example
You will need to do a replace on the input string using a method that allows you to use a custom function for replacement values. Then inside that function use the first capture value as the Key so to say and pull the correct corresponding value.
Since you did not specify what language you are using I will be nice and give you an example in C# and JS that I made for my own projects just recently.
Pseudo-Code
Loop through matches
Key is in first capture group
Check if replacements dict/obj/db/... has value for the Key
if Yes, return Value
else return ""
C#
email = Regex.Replace(email, #"\[\?&=(\w*)\]",
match => //match contains a Key & Replacements dict has value for that key
match?.Groups[1].Value != null
&& replacements.ContainsKey(match.Groups[1].Value)
? replacements[match.Groups[1].Value]
: "");
JS
var content = text.replace(/\[\?&=(\w*)\]/g,
function (match, p1) {
return replacements[p1] || "";
});

awk/regex: parsing error logs not always returned error description

I recently asked for help to parse out Java error stacks from a group of log files and got a very nice solution at the link below (using awk).
Pull out Java error stacks from log files
I marked the question answered and after some debugging and studying I found a few potential issues and since they are unrelated to my initial question but rather due to my limited understanding of awk and regular expressions, I thought it might be better to ask a new question.
Here is the solution:
BEGIN{ OFS="," }
/[[:space:]]+*<Error / {
split("",n2v)
while ( match($0,/[^[:space:]]+="[^"]+/) ) {
name = value = substr($0,RSTART,RLENGTH)
sub(/=.*/,"",name)
sub(/^[^=]+="/,"",value)
$0 = substr($0,RSTART+RLENGTH)
n2v[name] = value
print name value
}
code = n2v["ErrorCode"]
desc[code] = n2v["ErrorDescription"]
count[code]++
if (!seen[code,FILENAME]++) {
fnames[code] = (code in fnames ? fnames[code] ", " : "") FILENAME
}
}
END {
print "Count", "ErrorCode", "ErrorDescription", "Files"
for (code in desc) {
print count[code], code, desc[code], fnames[code]
}
}
One issue I am having with it is that not all ErrorDescriptions are being captured. For example, this error description appears in the output of this script:
ErrorDescription="Database Error."
But this error description does not appear in the results (description copied from actual log file):
ErrorDescription="Operation not allowed for reason code "7" on table "SCHEMA.TABLE".. SQLCODE=-668, SQLSTATE=57016, DRIVER=4.13.127"
Nor does this one:
ErrorDescription="Cannot Find Person For Given Order."
It seems that most error descriptions are not being returned by this script but do exist in the log file. I don't see why some error descriptions would appear and some not. Does anyone have any ideas?
EDIT 1:
Here is a sample of the XML I am parsing:
<Errors>
<Error ErrorCode="ERR_0139"
ErrorDescription="Cannot Find Person For Given Order." ErrorMoreInfo="">
...
...
</Error>
</Errors>
The pattern in the script will not match your data:
/[[:space:]]+*<Error / {
Details:
The "+" tells it to match at least one space.
The space after "Error" tells it to match another space - but your data has no space before the "=".
The "<" is unnecessary (but not part of the problem).
This would be a better pattern:
/^[[:space:]]*ErrorDescription[[:space:]]*=[[:space:]]*".*"/
This regex would only match the error description.
ErrorDescription="(.+?)"
It uses a capturing group to remember your error description.
Demo here. (Tested against a combination of your edit and your previous question error log.)

Validate input from an inputbox without leaving the inputbox

I created a function with an inputdialog to move lines conditionally (tnx to Romainl).
First thing to do is a search, then to invoke the code below.
My Code:
if !exists("char")
let char = "Move Lines with search match after/before?
\ \n
\ \nMove Line Backwards: Start input with: '?'
\ \nMove Line Forwards: Start input with: '/'
\ \n
\ \np.e.
\ \n?=\\s*$
\"
endif
let a = inputdialog(char)
if a == ""
return
endif
if matchstr(a, '^?') != ''
let minplus = '-'
elseif matchstr(a, '^/') != ''
let minplus = '+'
else
echo "wrong input: input does not start with '?' or '/'"
return
endif
I would like to change the "return" command in a "return back to inputdialog" command:
I would like to check the input entered in the inputbox immediately without leaving the inputbox, is that possible?
The call to inputdialog() is a single, blocking call in Vimscript. None of your code can run while it's open. No events (that can be hooked into with :autocmd are fired. In general, there's no parallelism in Vim.
The best you can do is re-launch the inputdialog() (possibly initialized with the previously entered text) when the validation fails.
Alternatively, you'd have to implement your own input control (e.g. using getchar()). There, you can run validation while waiting for the next pressed character.

How can I make a regex to find instances of the word Project not in square brackets?

For example:
$lang['Select Project'] = 'Select Project OK';
$lang['Project'] = 'Project';
I want to find only the instances of the word 'Project' not contained within the square brackets.
I'm using ColdFusion studio's extended replace utility to do a global replace.
Any suggestions?
Code Sample Follows:
<?php
$lang['Project Message Board'] = 'Project Message Board';
$lang['Project'] = 'Project';
$lang['Post Message'] = 'Post Message';
$lang['To'] = 'To';
$lang['Everyone'] = 'Everyone';
$lang['From'] = 'From';
$lang['Private Messsage'] = 'Private Messsage';
$lang['Note: Only private message to programmer'] = '[ Note: Please enter programmers id for private message with comma separate operator ]';
$lang['Select Project'] = 'Select Project';
$lang['message_validation'] = 'Message';
$lang['You must be logged in as a programmer to post messages on the Project Message Board'] = 'You must be logged in as a programmer to post messages on the Project Message Board';
$lang['Your Message Has Been Posted Successfully'] = 'Your message has been posted successfully';
$lang['You must be logged to post messages on the Project Message Board'] = 'You must be logged to post messages on the Project Message Board';
$lang['You must be post project to invite programmers'] = 'You must be post project to invite programmers';
$lang['You must be logged to invite programmers'] = 'You must be logged to invite programmers';
$lang['There is no open project to Post Mail'] = 'There is no open project to Post Mail';
$lang['You are currently logged in as']='You are currently logged in as';
$lang['Tip']='Tip: You can post programming code by placing it within [code] and [/code] tags.';
$lang['Submit']='Submit';
$lang['Preview']='Preview';
$lang['Hide']='Hide';
$lang['Show']='Show';
$lang['You are currently logged in as']='You are currently logged in as';
A regexp for 'Project' to the right of an equals sign would be:
/=.*Project/
a regexp that also does what you ask for, 'Project' that has no equals sign to its right would be:
/Project[^=]*$/
or a match of your example lines comes to:
/^\$lang['[^']+']\s+=\s+'Project';$/
By placing 'Project' in brackets () you can use that match in a replacement, adding the flag /g finds all occurences in the line.
Edit: Below didn't work because look-behind assertions have to be fixed-length. I am guessing that you want to do this because you want to do a global replace of "Project" with something else. In that case, borrowing rsp's idea of matching a 'Project' that is not followed by an equals sign, this should work:
/Project(?![^=]*\=)/
Here is some example code:
<?php
$str1 = "\$lang['Select Project'] = 'Select Project OK';";
$str2 = "\$lang['Project'] = 'Project';";
$str3 = "\$lang['No Project'] = 'Not Found';";
$str4 = "\$lang['Many Project'] = 'Select Project owner or Project name';";
$regex = '/Project(?![^=]*\=)/';
echo "<pre>\n";
//prints: $lang['Select Project'] = 'Select Assignment OK';
echo preg_replace($regex, 'Assignment', $str1) . "\n";
//prints: $lang['Project'] = 'Assignment';
echo preg_replace($regex, 'Assignment', $str2) . "\n";
//prints: $lang['No Project'] = 'Not Found';
echo preg_replace($regex, 'Assignment', $str3) . "\n";
//prints: $lang['Many Project'] = 'Select Assignment owner or Assignment name';
echo preg_replace($regex, 'Assignment', $str4) . "\n";
This should work:
/(?<=\=.*)Project/
That will match only the word "Project" if it appears after an equals sign. This means you could use it in a substitution too, if you want to replace "Project" on the right-hand-side with something else.
Thx for help. Not sure what is unclear? I just want to find all instances of the word 'Project' but only instances to the right of the equals sign (i.e. not included in square brackets). Hope that helps.
This actually looks like a tricky problem. Consider
[blah blah [yakkity] Project blah] Project [blah blah] [ Project
This is a parsing problem, and I don't know of any way to do it with one regex (but would be glad to learn one!). I'd probably do it procedurally, eliminating the pairs of brackets that did not contain other pairs until there were none left, then matching "Project".
While it's not clear what instances you want to find exactly, this will do:
^.+? = (.+?);
But you might consider using simple string manipulation of your language of choice.
edit
^.+?=.+?(Project).+?;$
will only match lines that have string Project after the equal sign.
[^\[]'[^'\[\]]+'[^\]] seems to accomplish what you want!
This one: [^\[]'[^'\[\]]*Project[^'\[\]]*' will find all strings, not inside of the file that are contained in quotes, and contain the word project.
Another edit: [^\[]'(?<ProjectString>[^'\[\]]*Project[^'\[\]]*)'[^\]]
This one matches the string, and returns it as the group "ProjectString". Any regex library should be able to pull that out sufficiently.