Replacing non alphabetical characters & numbers with other special characters - regex

I am using the following code to take out anything other than alphabetical characters, numbers, question mark, exclamation point, periods, parenthesis, commas & hyphen:
MsgBox(System.Text.RegularExpressions.Regex.Replace("hello to you's! My # is (442) 523-5584. #$%^*<>{}[]\|/?,+-=:;`~", "[^A-Za-z0-9]", ""))
I come up with this: hellotoyousMy#is4425235584
It should read like so: hello to yous! My # is (442) 523-5584.?,

Simply add all characters to your negated character class (take note of the space character!):
MsgBox(System.Text.RegularExpressions.Regex.Replace("hello to you's! My # is (442) 523-5584. #$%^*<>{}[]\|/?,+-=:;`~", "[^A-Za-z0-9 ?!.(),#-]+", ""))
(I also added a repeating + to your regex, so it can replace consecutive disallowed characters in one go)

Add a space and other symbols in the regex:
MsgBox(System.Text.RegularExpressions.Regex.Replace("hello to you's! My # is (442) 523-5584. #$%^*<>{}[]\|/?,+-=:;`~", "[^A-Za-z0-9 \(\)\!\.,\-\?]", ""))

Regex.Replace("your text", "[^A-Za-z0-9 ?!.(),-]+", "")
It [^A-Za-z0-9 ?!.(),-]+ will grab all unwanted characters following one after another and replace them by ""

Related

Regexp to extract studyinstanceuid from dump

I need to capture numbers and dots between brackets on lines containing the string 0020,000d, for example:
I: (0020,000d) UI [1.2.410.200001.1104.20160720104648421 ] # 38, 1 StudyInstanceUID
Using this regexp 0020,000d.*\[([\.0-9]+)\] I can match the needed value only if it doesn't have a space inside the brackets. How can I match the needed value ignoring any other character?.
Edit
If I use this regexp 0020,000d.*\[([\.0-9(\s|^\s))]+)\] I can capture numbers and dots and/or spaces, now if the string contains a space how can I capture in a group everything but the space?.
To clarify, I want to extract the 1.2.410.200001.1104.20160720104648421 string.
Codifying my (apparently helpful) answer from the comments:
You just need to allow zero or more spaces after the numbers-and-dots sequence before the closing bracket:
0020,000d.*\[([.0-9]+) *\]
Also, please note that you don't need to escape a dot in a character class.
Try this
let regex = /(?!\[)[.\d]+(?=[(\s)*\]])/g
let str = 'I: (0020,000d) UI [1.2.410.200001.1104.20160720104648421 ]'
let result = str.match(regex);
console.log(result);

Extracting plus (+), minus (-), and period (.) characters and all numbers [0-9] from a character string in R

I have many character strings that look like this, with a large variance of numbers:
tester1 <- "{\"fullgame\":\"-303\"}"
tester2 <- "{\"fullgame\":\"+7.5\"}"
I would like to extract plus(+), minus(-), and period(.) characters, along with all numbers[0-9] from my strings. I would also like to preserve the current order of each of these elements as they appear in the string.
I want the resulting strings to be:
formatted1 = "-303"
formatted2 = "+7.5"
I know that functions like gsub, strsplit, and regex would be ideal for this application, but for the life of me, I can't figure out the Perl syntax =(.
Any help would be greatly appreciated! Thank you guys!
Your strings look like json a lot. See the wiki page for more info. You shouldn't try to parse them with regex; rely instead on a specific json parser. There are many in R. Extracting the desired quantity is as easy as:
require(jsonlite) #other libraries: rjson, RJSONIO
fromJSON(tester1)
#$fullgame
#[1] "+7.5"
I don't know about "Perl" but this regex pattern pulls your numbers out:
> gsub( "([^-+]+)([+-]{0,1}[0-9.]+)(.+)", "\\2", c(tester1,tester2) )
[1] "-303" "+7.5"
Breaking apart the pattern which has three capture sections:
([^-+]+) : uses the negation operator in a character class to match any sequence that is
not a plus or minus sign
([+-]{0,1}[0-9.]+) : the second capture class allows (but does not require) a single
+/- sign, followed by any number of digits or decimal point/period
(.+) : is the third capture class ... anything else that is trailing
This one is a bit more specific about what form the numbers and decimal points can assume by adding optional single decimal point and subsequent digits:
gsub( "([^-+]+)([+-]{0,1}[0-9]+[.]{0,1}[0-9]*)(.+)", "\\2", c(tester1,tester2) )
I'm pretty sure that there are earlier postings that covered extraction of signed decimal numbers.
You can gsub out anything that doesn't match the type of characters you're looking for:
gsub('[^+-.0-9]', '', tester1)
# [1] "-303"
gsub('[^+-.0-9]', '', tester2)
# [1] "+7.5"
[^ ... ] defines a set of characters ... where the ^ tells it to match anything except for them. gsub then replaces all those characters with nothing, leaving you with what you want.

Regex to grab formulas

I am trying to parse a file that contains parameter attributes. The attributes are setup like this:
w=(nf*40e-9)*ng
but also like this:
par_nf=(1) * (ng)
The issue is, all of these parameter definitions are on a single line in the source file, and they are separated by spaces. So you might have a situation like this:
pd=2.0*(84e-9+(1.0*nf)*40e-9) nf=ng m=1 par=(1) par_nf=(1) * (ng) plorient=0
The current algorithm just splits the line on spaces and then for each token, the name is extracted from the LHS of the = and the value from the RHS. My thought is if I can create a Regex match based on spaces within parameter declarations, I can then remove just those spaces before feeding the line to the splitter/parser. I am having a tough time coming up with the appropriate Regex, however. Is it possible to create a regex that matches only spaces within parameter declarations, but ignores the spaces between parameter declarations?
Try this RegEx:
(?<=^|\s) # Start of each formula (start of line OR [space])
(?:.*?) # Attribute Name
= # =
(?: # Formula
(?!\s\w+=) # DO NOT Match [space] Word Characters = (Attr. Name)
[^=] # Any Character except =
)* # Formula Characters repeated any number of times
When checking formula characters, it uses a negative lookahead to check for a Space, followed by Word Characters (Attribute Name) and an =. If this is found, it will stop the match. The fact that the negative lookahead checks for a space means that it will stop without a trailing space at the end of the formula.
Live Demo on Regex101
Thanks to #Andy for the tip:
In this case I'll probably just match on the parameter name and equals, but replace the preceding whitespace with some other "parse-able" character to split on, like so:
(\s*)\w+[a-zA-Z_]=
Now my first capturing group can be used to insert something like a colon, semicolon, or line-break.
You need to add Perl tag. :-( Maybe this will help:
I ended up using this in C#. The idea was to break it into name value pairs, using a negative lookahead specified as the key to stop a match and start a new one. If this helps
var data = #"pd=2.0*(84e-9+(1.0*nf)*40e-9) nf=ng m=1 par=(1) par_nf=(1) * (ng) plorient=0";
var pattern = #"
(?<Key>[a-zA-Z_\s\d]+) # Key is any alpha, digit and _
= # = is a hard anchor
(?<Value>[.*+\-\\\/()\w\s]+) # Value is any combinations of text with space(s)
(\s|$) # Soft anchor of either a \s or EOB
((?!\s[a-zA-Z_\d\s]+\=)|$) # Negative lookahead to stop matching if a space then key then equal found or EOB
";
Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture)
.OfType<Match>()
.Select(mt => new
{
LHS = mt.Groups["Key"].Value,
RHS = mt.Groups["Value"].Value
});
Results:

Regex to create url friendly string

I want to create a url friendly string (one that will only contain letters, numbers and hyphens) from a user input to :
remove all characters which are not a-z, 0-9, space or hyphens
replace all spaces with hyphens
replace multiple hyphens with a single hyphen
Expected outputs :
my project -> my-project
test project -> test-project
this is # long str!ng with spaces and symbo!s -> this-is-long-strng-with-spaces-and-symbos
Currently i'm doing this in 3 steps :
$identifier = preg_replace('/[^a-zA-Z0-9\-\s]+/','',strtolower($project_name)); // remove all characters which are not a-z, 0-9, space or hyphens
$identifier = preg_replace('/(\s)+/','-',strtolower($identifier)); // replace all spaces with hyphens
$identifier = preg_replace('/(\-)+/','-',strtolower($identifier)); // replace all hyphens with single hyphen
Is there a way to do this with one single regex ?
Yeah, #Jerry is correct in saying that you can't do this in one replacement as you are trying to replace a particular string with two different items (a space or dash, depending on context). I think Jerry's answer is the best way to go about this, but something else you can do is use preg_replace_callback. This allows you to evaluate an expression and act on it according to what the match was.
$string = 'my project
test project
this is # long str!ng with spaces and symbo!s';
$string = preg_replace_callback('/([^A-Z0-9]+|\s+|-+)/i', function($m){$a = '';if(preg_match('/(\s+|-+)/i', $m[1])){$a = '-';}return $a;}, $string);
print $string;
Here is what this means:
/([^A-Z0-9]+|\s+|-+)/i This looks for any one of your three quantifiers (anything that is not a number or letter, more than one space, more than one hyphen) and if it matches any of them, it passes it along to the function for evaluation.
function($m){ ... } This is the function that will evaluate the matches. $m will hold the matches that it found.
$a = ''; Set a default of an empty string for the replacement
if(preg_match('/(\s+|-+)/i', $m[1])){$a = '-';} If our match (the value stored in $m[1]) contains multiple spaces or hyphens, then set $a to a dash instead of an empty string.
return $a; Since this is a function, we will return the value and that value will be plopped into the string wherever it found a match.
Here is a working demo
I don't think there's one way of doing that, but you could reduce the number of replaces and in an extreme case, use a one liner like that:
$text=preg_replace("/[\s-]+/",'-',preg_replace("/[^a-zA-Z0-9\s-]+/",'',$text));
It first removes all non-alphanumeric/space/dash with nothing, then replaces all spaces and multiple dashes with a single one.
Since you want to replace each thing with something different, you will have to do this in multiple iterations.
Sorry D:

Regular expression help - comma delimited string

I don't write many regular expressions so I'm going to need some help on the one.
I need a regular expression that can validate that a string is an alphanumeric comma delimited string.
Examples:
123, 4A67, GGG, 767 would be valid.
12333, 78787&*, GH778 would be invalid
fghkjhfdg8797< would be invalid
This is what I have so far, but isn't quite right: ^(?=.*[a-zA-Z0-9][,]).*$
Any suggestions?
Sounds like you need an expression like this:
^[0-9a-zA-Z]+(,[0-9a-zA-Z]+)*$
Posix allows for the more self-descriptive version:
^[[:alnum:]]+(,[[:alnum:]]+)*$
^[[:alnum:]]+([[:space:]]*,[[:space:]]*[[:alnum:]]+)*$ // allow whitespace
If you're willing to admit underscores, too, search for entire words (\w+):
^\w+(,\w+)*$
^\w+(\s*,\s*\w+)*$ // allow whitespaces around the comma
Try this pattern: ^([a-zA-Z0-9]+,?\s*)+$
I tested it with your cases, as well as just a single number "123". I don't know if you will always have a comma or not.
The [a-zA-Z0-9]+ means match 1 or more of these symbols
The ,? means match 0 or 1 commas (basically, the comma is optional)
The \s* handles 1 or more spaces after the comma
and finally the outer + says match 1 or more of the pattern.
This will also match
123 123 abc (no commas) which might be a problem
This will also match 123, (ends with a comma) which might be a problem.
Try the following expression:
/^([a-z0-9\s]+,)*([a-z0-9\s]+){1}$/i
This will work for:
test
test, test
test123,Test 123,test
I would strongly suggest trimming the whitespaces at the beginning and end of each item in the comma-separated list.
You seem to be lacking repetition. How about:
^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$
I'm not sure how you'd express that in VB.Net, but in Python:
>>> import re
>>> x [ "123, $a67, GGG, 767", "12333, 78787&*, GH778" ]
>>> r = '^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$'
>>> for s in x:
... print re.match( r, s )
...
<_sre.SRE_Match object at 0xb75c8218>
None
>>>>
You can use shortcuts instead of listing the [a-zA-Z0-9 ] part, but this is probably easier to understand.
Analyzing the highlights:
[a-zA-Z0-9 ]+ : capture one or more (but not zero) of the listed ranges, and space.
(?:[...]+,)* : In non-capturing parenthesis, match one or more of the characters, plus a comma at the end. Match such sequences zero or more times. Capturing zero times allows for no comma.
[...]+ : capture at least one of these. This does not include a comma. This is to ensure that it does not accept a trailing comma. If a trailing comma is acceptable, then the expression is easier: ^[a-zA-Z0-9 ,]+
Yes, when you want to catch comma separated things where a comma at the end is not legal, and the things match to $LONGSTUFF, you have to repeat $LONGSTUFF:
$LONGSTUFF(,$LONGSTUFF)*
If $LONGSTUFF is really long and contains comma repeated items itself etc., it might be a good idea to not build the regexp by hand and instead rely on a computer for doing that for you, even if it's just through string concatenation. For example, I just wanted to build a regular expression to validate the CPUID parameter of a XEN configuration file, of the ['1:a=b,c=d','2:e=f,g=h'] type. I... believe this mostly fits the bill: (whitespace notwithstanding!)
xend_fudge_item_re = r"""
e[a-d]x= #register of the call return value to fudge
(
0x[0-9A-F]+ | #either hardcode the reply
[10xks]{32} #or edit the bitfield directly
)
"""
xend_string_item_re = r"""
(0x)?[0-9A-F]+: #leafnum (the contents of EAX before the call)
%s #one fudge
(,%s)* #repeated multiple times
""" % (xend_fudge_item_re, xend_fudge_item_re)
xend_syntax = re.compile(r"""
\[ #a list of
'%s' #string elements
(,'%s')* #repeated multiple times
\]
$ #and nothing else
""" % (xend_string_item_re, xend_string_item_re), re.VERBOSE | re.MULTILINE)
Try ^(?!,)((, *)?([a-zA-Z0-9])\b)*$
Step by step description:
Don't match a beginning comma (good for the upcoming "loop").
Match optional comma and spaces.
Match characters you like.
The match of a word boundary make sure that a comma is necessary if more arguments are stacked in string.
Please use - ^((([a-zA-Z0-9\s]){1,45},)+([a-zA-Z0-9\s]){1,45})$
Here, I have set max word size to 45, as longest word in english is 45 characters, can be changed as per requirement