I am trying to mask the SSN which is in "123-12-1234" to "XXX-XX-1234". I am able achieve using the below code.
string input = " 123-12-1234 123-11-1235 ";
Match m = Regex.Match(input, #"((?:\d{3})-(?:\d{2})-(?<token>\d{4}))");
while (m.Success)
{
if (m.Groups["token"].Length > 0)
{
input = input.Replace(m.Groups[0].Value,"XXX-XX-"+ m.Groups["token"].Value);
}
m = m.NextMatch();
}
Is there a better way to do it in one line using the Regex.Replace method.
You can try the following:
string input = " 123-12-1234 123-11-1235";
string pattern = #"(?:\d{3})-(?:\d{2})-(\d{4})";
string result = Regex.Replace(input, pattern, "XXX-XX-$1");
Console.WriteLine(result); // XXX-XX-1234 XXX-XX-1235
If your are going to be doing a lot of masking you should consider a few whether to use compiled regular expression or not.
Using them will cause a slight delay when the application is first run, but they will run faster subsequently.
Also the choice of static vs instances of the Regex should be considered.
I found the following to be the most efficient
public class SSNFormatter
{
private const string IncomingFormat = #"^(\d{3})-(\d{2})-(\d{4})$";
private const string OutgoingFormat = "xxxx-xx-$3";
readonly Regex regexCompiled = new Regex(IncomingFormat, RegexOptions.Compiled);
public string SSNMask(string ssnInput)
{
var result = regexCompiled.Replace(ssnInput, OutgoingFormat);
return result;
}
}
There is a comparison of six methods for regex checking/masking here.
Related
i am trying to validate input string to chech whether it contains '+' symbol anywhere in the string. i used for of loop but didnt get what is exprected.
const isMobileValidWithoutPlus = funcLib.isValidMobileWithoutPlus(mobileNumber);
isValidMobileWithoutPlus(mobileNumber) {
if (!mobileNumber) {
return false;
}
const checkRegex = new RegExp('\\+?\\d+');
return checkRegex.test(mobileNumber);
}
but able to get desired out.
The regex for this would be
const rgx = new RegExp(/\+/gm);
Your regular expression checks if you have a string that can either start with + or not, and is followed by one or more numbers. But you're saying you want to just check if there's a "+" anywhere in the number. For that you can use this regex above.
Also, do you need to use a regex?
You can do this using indexOf on a string if using regex is not a must.
let number = "+001234";
function hasPlus(number) {
return number.indexOf('+') !== -1;
}
Regular expressions are generally useful when you don't have one specific string that you're looking for, or when you want to find all the apparitions of a regex in a longer string. In your case, checking if a string contains "+", it isn't necessary to use them.
I want to get number of sub-string matches of a given string using re2;
I have read the codes of re2: https://github.com/google/re2/blob/master/re2/re2.h but do not see an easy way to do that.
I have following sample code:
std::string regexPunc = "[\\p{P}]"; // matches any punctuations;
re2::RE2 re2Punc(regexPunc);
std::string sampleString = "test...test";
if (re2::RE2::PartialMatch(sampleString, re2Punc)) {
std::cout << re2Punc.numOfMatches();
}
I want it to output 3 as there are three punctuations in the string;
Use FindAndConsume, and count the matches yourself. It won't be inefficient, because in order to know the number of matches, those matches would have to be performed and counted anyway.
Example:
std::string regexPunc = "[\\p{P}]"; // matches any punctuations;
re2::RE2 re2Punc(regexPunc);
std::string sampleString = "test...test";
StringPiece input(sampleString);
int numberOfMatches = 0;
while(re2::RE2::FindAndConsume(&input, re2Punc)) {
++numberOfMatches;
}
I need to extract a list of all allowed characters from a given regular expression.
So for example, if the regex looks like this (some random example):
[A-Z]*\s+(4|5)+
the output should be
ABCDEFGHIJKLMNOPQRSTUVWXYZ45
(omitting the whitespace)
One obvious solution would be to define a complete set of allowed characters, and use a find method, to return the corresponding subsequence for each character. This seems to be a bit of a dull solution though.
Can anyone think of a (possibly simple) algorithm on how to implement this?
One thing you can do is:
split the regex by subgroup
test the char panel against the subgroup
See the following example (not perfect yet) c#:
static void Main(String[] args)
{
Console.WriteLine($"-->{TestRegex(#"[A-Z]*\s+(4|5)+")}<--");
}
public static string TestRegex(string pattern)
{
string result = "";
foreach (var subPattern in Regex.Split(pattern, #"[*+]"))
{
if(string.IsNullOrWhiteSpace(subPattern))
continue;
result += GetAllCharCoveredByRegex(subPattern);
}
return result;
}
public static string GetAllCharCoveredByRegex(string pattern)
{
Console.WriteLine($"Testing {pattern}");
var regex = new Regex(pattern);
var matches = new List<char>();
for (var c = char.MinValue; c < char.MaxValue; c++)
{
if (regex.IsMatch(c.ToString()))
{
matches.Add(c);
}
}
return string.Join("", matches);
}
Which outputs:
Testing [A-Z]
Testing \s
Testing (4|5)
-->ABCDEFGHIJKLMNOPQRSTUVWXYZ
? ? ???????? 45<--
I use Microsoft Visual Studio and have a file with some text delimited by | . I need to find a particular pattern and remove it from the file
sometext|maxusage=sometext,,,,...|somemoretext
I want to isolate any | followed by maxusage= , followed by any text upto next |
in the above case, I need to isolate
|maxusage=sometext,,,,...|
its simple and single statement
File.WriteAllText("c:\\test.txt", Regex.Replace(File.ReadAllText("c:\\test.txt"), "\|maxusage=[^\|]+\|", ""));
Note that it certainly works (it would not in case visual studio doesn't implement lazy quantifiers):
/\|maxusage=.*?\|/
use this regex \|maxusage.*?\|
Why not use string.Split() in order to split your string and investigate it?
string[] parts = text.Split('|');
foreach(string s in parts){
//iterate of array and find what you are looking for
}
Here is C# code my friend,
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = #"\p{Sc}*(?<amount>\s?\d+[.,]?\d*)\p{Sc}*";
string replacement = "${amount}";
string input = "$16.32 12.19 £16.29 €18.29 €18,29";
string result = Regex.Replace(input, pattern, replacement);
Console.WriteLine(result);
}
}
// The example displays the following output:
// 16.32 12.19 16.29 18.29 18,29
What's the easiest way to do an "instring" type function with a regex? For example, how could I reject a whole string because of the presence of a single character such as :? For example:
this - okay
there:is - not okay because of :
More practically, how can I match the following string:
//foo/bar/baz[1]/ns:foo2/#attr/text()
For any node test on the xpath that doesn't include a namespace?
(/)?(/)([^:/]+)
Will match the node tests but includes the namespace prefix which makes it faulty.
I'm still not sure whether you just wanted to detect if the Xpath contains a namespace, or whether you want to remove the references to the namespace. So here's some sample code (in C#) that does both.
class Program
{
static void Main(string[] args)
{
string withNamespace = #"//foo/ns2:bar/baz[1]/ns:foo2/#attr/text()";
string withoutNamespace = #"//foo/bar/baz[1]/foo2/#attr/text()";
ShowStuff(withNamespace);
ShowStuff(withoutNamespace);
}
static void ShowStuff(string input)
{
Console.WriteLine("'{0}' does {1}contain namespaces", input, ContainsNamespace(input) ? "" : "not ");
Console.WriteLine("'{0}' without namespaces is '{1}'", input, StripNamespaces(input));
}
static bool ContainsNamespace(string input)
{
// a namspace must start with a character, but can have characters and numbers
// from that point on.
return Regex.IsMatch(input, #"/?\w[\w\d]+:\w[\w\d]+/?");
}
static string StripNamespaces(string input)
{
return Regex.Replace(input, #"(/?)\w[\w\d]+:(\w[\w\d]+)(/?)", "$1$2$3");
}
}
Hope that helps! Good luck.
Match on :? I think the question isn't clear enough, because the answer is so obvious:
if(Regex.Match(":", input)) // reject
You might want \w which is a "word" character. From javadocs, it is defined as [a-zA-Z_0-9], so if you don't want underscores either, that may not work....
I dont know regex syntax very well but could you not do:
[any alpha numeric]\*:[any alphanumeric]\*
I think something like that should work no?
Yeah, my question was not very clear. Here's a solution but rather than a single pass with a regex, I use a split and perform iteration. It works as well but isn't as elegant:
string xpath = "//foo/bar/baz[1]/ns:foo2/#attr/text()";
string[] nodetests = xpath.Split( new char[] { '/' } );
for (int i = 0; i < nodetests.Length; i++)
{
if (nodetests[i].Length > 0 && Regex.IsMatch( nodetests[i], #"^(\w|\[|\])+$" ))
{
// does not have a ":", we can manipulate it.
}
}
xpath = String.Join( "/", nodetests );