Regular expression to amend Sysprep.inf file - regex

I currently have a requirement to parse a sysprep.inf file and insert a value input by the end user.
I'm coding this utility using AutoIT and my regular expression is slightly out.
The line I need amending is as follows:
ComputerName=%DeviceName%
DeviceName is variable injected by LANDesk. If the device has previously been in the LANDesk database the name is injected into the file. If not the variable name remains. The device name must go after the =
Here is a snippet of my current code:
$FileContents = StringRegExpReplace($FileContents,'ComputerName=[a-z]','ComputerName='& $deviceNameInput)
Thanks for any guidance anyone can offer.

I'm not familiar with AutoIT or BASIC... but it looks like you need to be using something like this:
$FileContents = StringRegExpReplace($FileContents,'.*ComputerName=(\%[a-zA-Z]*\%).*', $deviceNameInput)
OR
$FileContents = StringRegExpReplace($FileContents,'ComputerName=\%[a-zA-Z]*\%', 'ComputerName='&$deviceNameInput)
this will only replace a device name that's a-z or A-Z. Not numerical or containing spaces.

Writing regular expressions can be tough because there are so many dialects of regular expressions. Assuming you are using a regex library that supports a Perl-like dialect you might want to try this for your regex:
^\s*ComputerName\s*=\s*(?:%DeviceName%|[a-zA-Z0-9_-]+)
Basically this regex will match an lines either the litteral string ComputerName=%DeviceName% or ComputerName=<some actual device name that only contains the characters a-z, A-Z, 0-9, _, and ->. This regex is also a bit lenient in that it will match a line that contains whitespace at the beginning of the line as well as before and/or after the equals sign. The image below explains the components of this regex in greater detail.
p.s. that image was generated by RegexBuddy, an excellent regular expression IDE.

Autoit has a great way of dealing with ini files - IniWrite
IniWrite("SysPrep.ini", "write_section_here", "ComputerName", $deviceNameInput)
creates or updates SysPrep.ini with:
[write_section_here]
ComputerName=localhost

Related

Writing valid RegEx for use in file/folder exclusion

I'm trying to write two expressions to use in the files/folder Exclusion List for Code42 CrashPlan backup. Their support won't help with RegEx expressions, they just point me to their KB article.
In their "File Exclusions" section, I'd like to:
exclude this folder specifically: S:\Google Drive\Temp
any file or folder containing the string Backup_Excluded anywhere in its name.
This is what I've got so far - but I have no way of knowing if they're correct:
(?i).*Google Drive\\Temp ...but since I really want to exclude a specific folder, not a pattern - do I need to escape the slashes and colon in the path of S:\Google Drive\Temp
(?i).*Backup_Excluded
Research disclaimer: I know there are RegEx resources out there, but am unsure which flavor/syntax to use, as I'd imagine there are many. I was hoping those with more RegEx familiarity could advise.
The link you posted says:
The Code42 app treats all file separators as forward slashes /.
So it seems you'd want to use / instead of \\ in your regular expressions.
Colon doesn't need escaping.
\ needs escaping because it's the escaping character itself.
/ normally needs escaping because it is the default separators for regular expression sections. However, the examples in your link don't escape it, so only the matching section is implied, so no escaping.
Then you could probably use:
S:/Google Drive/Temp
or [A-Z]:/Google Drive/Temp (to allow any drive)
.*Backup_Excluded.*
I probably wouldn't use (?i), as the capitals in those strings are usually there, but that's your call.
Check out e.g. https://regex101.com/ to test your regular expressions (also in different flavours).

regular expression matching filename with multiple extensions

Is there a regular expression to match the some.prefix part of both of the following filenames?
xyz can be any character of [a-z0-9-_\ ]
some.prefix part can be any character in [a-zA-Z0-9-_\.\ ].
I intentionally included a . in some.prefix.
some.prefix.xyz.xyz
some.prefix.xyz
I have tried many combinations. For example:
(?P<prefix>[a-zA-Z0-9-_\.]+)(?:\.[a-z0-9]+\.gz|\.[a-z0-9]+)
It works with abc.def.csv by catching abc.def, but fail to catch it in abc.def.csv.gz.
I primarily use Python, but I thought the regex itself should apply to many languages.
Update: It's not possible, see discussion with #nowox below.
I think your regex works pretty well. I recommend you to trying regex101 with your example:
https://regex101.com/r/dV6cE8/3
The expression
^(?i)[ \w-]+\.[ \w-]+
Should work in your case:
som e.prefix.xyz.xyz
^^^^^^^^^^^
some.prefix.xyz
^^^^^^^^^^^
abc.def.csv.gz
^^^^^^^
And in Python you can use:
import re
text = """some.prefix.xyz.xyz
some.prefix.xyz
abc.def.csv.gz"""
print re.findall('^(?i)[ \w-]+\.[ \w-]+', text, re.MULTILINE)
Which will display:
['som e.prefix', 'some.prefix', 'abc.def']
I might think you are a bit confused about your requirement. If I summarize, you have a pathname made of chars and dot such as:
foo.bar.baz.0
foobar.tar.gz
f.o.o.b.a.r
How would you separate these string into a base-name and an extension? Here we recognize some known patterns .tar.gz is definitely an extension, but is .bar.baz.0 the extension or it is only .0?
The answer is not easy and no regexes in this World would be able to guess the correct answer at 100% without some hints.
For example you can list the acceptable extensions and make some criteria:
An extension match the regex \.\w{1,4}$
Several extensions may be concatenated together (\.\w{1,4}){1,4}$
The remaining is called the basename
From this you can build this regular expression:
(?P<basename>.*?)(?P<extension>(?:\.\w{1,4}){1,4})$
Try this[a-z0-9-_\\]+\.[a-z0-9-_\\]+[a-zA-Z0-9-_\.\\]+

regex replace slash or ignore

I have particular text that looks like the following:
CLIA ID:
Rapid Strep Test w/reflex culture
My regex to grab "Rapid Strep Test w/reflex culture"
looks like this
(?<=CLIA\s*ID:\s*\n)[a-zA-Z_0-9 /]{1,30}
here is my problem, my program actually grabs the text and then using the text it renames the input file with what it grabbed. The bad thing is the sending system cannot NOT send the / and as we all know I cannot name a file with a slash in it in Windows. Is there a way for me to grab the first 30 characters and if it finds / anywhere to replace it with a space?? I would even be ok with a REGEX where it finds the / to keep it in the capture, but exclude it in the output so end results would be something like
Rapid Strep Test wreflex culture
(30 characters max as i have of course). but ultimately i would like it to output
Rapid Strep Test w reflex culture
any thoughts please?
"In theoretical computer science and formal language theory, a regular expression (abbreviated regex or regexp) is a sequence of characters that forms a search pattern, mainly for use in pattern matching with strings, or string matching" - Wikipedia, Regular Expressions
I don't think that doing this using just Regex is possible.
If you are using .NET, you can use the String replace method to replace all occurrences of a substring with a different substring. This is probably what you are looking for.
Here's a small try for a solution in JavaScript using a callback function. The same approach is possible in many other languages
text.replace(
/CLIA\s*ID:\s*\n([\w\s]{1,30}).*/,
function(s) {return s.replace('/', ' ');}
);

Regular Expressions with conditions

I have a string that looks like:
this is a string [[and]] it is [[awesome|amazing]]
I have the following regular expression so far:
(?<mygroup>(?<=\[\[).+?(?=\]\]))
I am basically trying to capture everything inside the brackets. However, I need to add another condition that says: If the matched result contains a pipe delimiter then only return the word to the right of the pipe delimiter. If there is no pipe then just return everything inside the brackets.
The parsing result I am looking for given the example above should look like:
and
amazing
Any input is appreciated.
(?<mygroup>(?<=\[\[)([^|\]]*|)?([^|]+?)(?=\]\]))
You could use this regex:
(?<=\[\[[^\]]*?)(?!\w+\|)\w+(?=\]\])
it matches both and and amazing words in your test example. You could check it out, I created a test app on Ideone.
From the regex info page:
The tremendous power and expressivity
of modern regular expressions can
seduce the gullible — or the foolhardy
— into trying to use regexes on every
string‐related task they come across.
My advice: Just grab what is between the brackets and parse it after.
Regular expressions are not the answer to everything. May those who follow after you be spared from deciphering the regex you come up with.

Help with an Emacs Regular Expression

I have statements like this all over my code:
LogWrite (String1,
String2,
L"=======format string======",
...
);
I want to change each of these to:
LogWrite (String1,
String2,
L"format string",
...
);
I'm trying to write the regexp required to do this using the Emacs function query-replace-regexp, but not much success yet. Help please!
UPDATE:
1) In case it is not clear, this question is emacs specific.
2) I would like to match the entire code chunk starting from Log... ending at );
3) I used the following reg-exp to match the code chunk:
L.*\n.*\n.*==.*;
I used re-builder to match this regexp. the \n is used because I found that otherwise emacs would stop matching at the new line. The problem is that I don't know how to select the format string and save it to use it in the replace regexp - hence the ==.* part in the regexp. That needs to be modified to save the format string.
If you don't have multiple (or escaped) double quotes in those format string lines, you can
//replace
L"=+(.*)=+"
//with
L"\1"
Update: Removed the lazy quantifier (thanks #tim). Make sure that the regex is not multiline; the greedy * will lead to pretty bad results if . matches new lines
A great tool to figure out emacs regular expressions is:
M-x re-builder
A brief description from the documentation:
When called up re-builder' attaches
itself to the current buffer which
becomes its target buffer, where all
the matching is done. The active
window is split so you have a view on
the data while authoring the RE. If
the edited expression is valid the
matches in the target buffer are
marked automatically with colored
overlays (for non-color displays see
below) giving you feedback over the
extents of the matched (sub)
expressions. The (non-)validity is
shown only in the modeline without
throwing the errors at you. If you
want to know the reason why RE Builder
considers it as invalid call
reb-force-update' ("\C-c\C-u") which
should reveal the error.
It comes built into Emacs (since 21)
And for the syntax of Emacs regular expressions, you can read these info pages:
Syntax of Regular Expressions
Backslash in Regular Expressions
/={7}(.*)={6}/\1/
this should do.