I would like to grab the first 4 characters of two words using RegEx. I have some RegEx experinece however a search did not yeild any results.
So if I have Awesome Sauce I would like the end result to be AwesSauc
Use the Replace Text action with the following parameters:
Pattern: \W*\b(\p{L}{1,4})\w*\W*
Replacement text: $1
See the regex demo.
Pattern details:
\W* - 0+ non-word chars (trim from the left)
\b - a leading word boundary
(\p{L}{1,4}) - Group 1 (later referred to via $1 backreference) matching any 1 to 4 letters (incl. Unicode ones)
\w* - any 0+ word chars (to match the rest of the word)
\W* - 0+ non-word chars (trim from the right)
I think this RegEx should do the job
string pattern = #"\b\w{4}";
var text = "The quick brown fox jumps over the lazy dog";
Regex regex = new Regex(pattern);
var match = regex.Match(text);
while (match.Captures.Count != 0)
{
foreach (var capture in match.Captures)
{
Console.WriteLine(capture);
}
match = match.NextMatch();
}
// outputs:
// quic
// brow
// jump
// over
// lazy
Alternatively you could use patterns like:
\b\w{1,4} => The, quic, brow, fox, jump, over, the, lazy, dog
\b[\w|\d]{1,4} => would also match digits
Update:
added a full example for C# and modified the pattern slightly. Also added some alternative patterns.
one approach with Linq
var res = new string(input.Split().SelectMany((x => x.Where((y, i) => i < 4))).ToArray());
Try this expression
\b[a-zA-Z0-9]{1,4}
Using regex would in fact be more complex and totally unnecessary for this case. Just do it as either of the below.
var sentence = "Awesome Sau";
// With LINQ
var linqWay = string.Join("", sentence.Split(" ".ToCharArray(), options:StringSplitOptions.RemoveEmptyEntries).Select(x => x.Substring(0, Math.Min(4,x.Length))).ToArray());
// Without LINQ
var oldWay = new StringBuilder();
string[] words = sentence.Split(" ".ToCharArray(), options:StringSplitOptions.RemoveEmptyEntries);
foreach(var word in words) {
oldWay.Append(word.Substring(0, Math.Min(4, word.Length)));
}
Edit:
Updated code based on #Dai's comment. Math.Min check borrowed as is from his suggestion.
Related
I'm filtering list like this but i think there should be better approach to filter list inside where bloc it is not allowing me to declare variable. is there any other way to achieve the same
var cc = contactsAll
.where(
(i) =>
regularExpression(i.displayName, 'dev') ||
regularExpression(i.displayName, 'soft') ||
regularExpression(i.displayName, 'angular') ||
regularExpression(i.displayName, 'java')
)
.toList();
my expression filter function
bool regularExpression(String stringg, String search) {
RegExp exp = new RegExp(
"\\b" + search + "\\b",
caseSensitive: false,
);
return exp.hasMatch(stringg);
}
Thanks in advance
You may build the pattern dynamically:
var keys = ['dev', 'soft', 'angular', 'java'];
var regex = new RegExp("\\b(?:${keys.join('|')})\\b", caseSensitive: false);
var contactsAll = ['No match', 'I like java', 'I like javascript'];
var cc = contactsAll.where( (i) => regex.hasMatch(i) ).toList();
print(cc); // => [I like java]
The regex will look like \b(?:dev|soft|angular|java)\b and will match any of the keywords inside the non-capturing group as a whole word due to the \b word boundaries. See the regex demo.
If the keys can contain special characters, but you still need a whole word search, you need to escape all special characters and use either unambiguous boundaries
var regex = new RegExp("(?:^|\\W)(?:${keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')).join('|')})(?!\\w)", caseSensitive: false);
This results in a (?:^|\W)(?:dev|soft|angular|java)(?!\w) pattern (see demo) where (?:^|\W) matches start of string or a non-word char and (?!\w) requires the absense of a word char immediately to the right of the current location.
The .map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')) part escapes the literal part for use within regex.
Or whitespace boundaries:
var regex = new RegExp("(?:^|\\s)(?:${keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')).join('|')})(?!\\S)", caseSensitive: false);
This results in a (?:^|\s)(?:dev|soft|angular|java)(?!\S) pattern where (?:^|\s) matches start of string or a whitespace char and (?!\S) requires the absense of a non-whitespace char immediately to the right of the current location.
See the regex demo.
Without creating a function, you can use the contains method on your displayName like this :
var cc = contactsAll
.where((i) =>
i.displayName.contains(RegExp('\\bdev\\b')) ||
i.displayName.contains(RegExp('\\bsoft\\b')) ||
i.displayName.contains(RegExp('\\bangular\\b')) ||
i.displayName.contains(RegExp('\\bjava\\b')),)
.toList();
Using notepad++, how can I replace the -s noted by the carats? The dashes I want to replace occurs every 7th character in the string.
11.871-2-2.737-2.00334-2
^ ^ ^
123456781234567812345678
It's pretty simple since it's only dashes:
(\S*?)-
Begin capture group.............................. (
Find any number of non-space chars... \S*
Lazily until...............................................?
End capture group...................................)
No capture find hyphen...........................-
Demo 1
var str = `11.871-2-2.737-2.00334-2`;
var sub = `$1`;
var rgx = /(\S*?)-/g;
var res = str.replace(rgx, sub);
console.log(res);
"There is a dash (right above 1) that I would like to preserve. This seems to get rid of all the dashes in the string"
The question clearly shows that there isn't a dash at the "1 position", but since there's a possibility that it's possible considering the pattern (n7). Don't have time to break it down, but I can refer you to a proper definition of the meta char \b.
Demo 2
var str = `-11.871-2-2.737-2.00334-2`;
var sub = `$1$2`;
var rgx = /\b[-]{1}(\S*?)-(\S*?)\b/g;
var res = str.replace(rgx, sub);
console.log(res);
Search for ([0-9\.-]{6,6})-
Replace with: $1MY_SEPARATOR
I have the following regex /\.(\w+)/g represented here
It's matching against this sample string: function () {__cov_0vpZ06dQffa98X1ZQ0lWVA.f['74']++;__cov_0vpZ06dQffa98X1ZQ0lWVA.s['211']++;return t.propertygroup.subproperty1;}
Right now it's matching "f.s.propertygroup.subproperty1", but I want it to match only "propertyGroup.subproperty1" or if it was just t.subproperty1 it would just match "subproperty1". So it should find all words after the first period, but only before the last occurrence of the semi-colon.
The function string above is dynamic (JavaScript) so it might add additional statements with additional semi-colons at any time, but I still want to match only the last return variable name.
I've been fighting this regex all day and you, a regex guru, could probably solve this in 5 minutes. Can you help?
Use a positive lookahead:
\.(\w+)(?=[^;]*;[^;]*$)
^^^^^^^^^^^^^^^^
See the regex demo
The (?=[^;]*;[^;]*$) will only match the . + word chars if they are followed with 0+ chars other than ;, then ; and again 0+ chars other than ; up to the end of string.
JS code:
var regex = /\.(\w+)(?=[^;]*;[^;]*$)/g;
var str = "function () {__cov_0vpZ06dQffa98X1ZQ0lWVA.f['74']++;__cov_0vpZ06dQffa98X1ZQ0lWVA.s['211']++;return t.propertygroup.subproperty1;}";
var res = [], m;
while ((m = regex.exec(str)) !== null) {
res.push(m[1]);
}
console.log(res);
Or another one:
var s = "function () {__cov_0vpZ06dQffa98X1ZQ0lWVA.f['74']++;__cov_0vpZ06dQffa98X1ZQ0lWVA.s['211']++;return t.propertygroup.subproperty1;}";
var res = s.match(/\.(\w+)(?=[^;]*;[^;]*$)/g).map(function(x) {return x.slice(1);});
console.log(res);
perhaps this is the one you need?
#"\.([a-zA-Z0-9_.]+)[^;]*;[^;]*}$"
demo
I am trying to replace a certain group to "" by using regex.
I was searching and doing my best, but it's over my head.
What I want to do is,
string text = "(12je)apple(/)(jj92)banana(/)cat";
string resultIwant = {apple, banana, cat};
In the first square bracket, there must be 4 character including numbers.
and '(/)' will come to close.
Here's my code. (I was using matches function)
string text= #"(12dj)apple(/)(88j1)banana(/)cat";
string pattern = #"\(.{4}\)(?<value>.+?)\(/\)";
Regex rex = new Regex(pattern);
MatchCollection mc = rex.Matches(text);
if(mc.Count > 0)
{
foreach(Match str in mc)
{
print(str.Groups["value"].Value.ToString());
}
}
However, the result was
apple
banana
So I think I should use replace or something else instead of Matches.
The below regex would capture the word characters which are just after to ),
(?<=\))(\w+)
DEMO
Your c# code would be,
{
string str = "(12je)apple(/)(jj92)banana(/)cat";
Regex rgx = new Regex(#"(?<=\))(\w+)");
foreach (Match m in rgx.Matches(str))
Console.WriteLine(m.Groups[1].Value);
}
IDEONE
Explanation:
(?<=\)) Positive lookbehind is used here. It sets the matching marker just after to the ) symbol.
() capturing groups.
\w+ Then it captures all the following word characters. It won't capture the following ( symbol because it isn't a word character.
I am developing a windows application in C#. I have been searching for the solution to my problem in creating a Regex pattern. I want to create a Regex pattern matching the either of the following strings:
XD=(111111) XT=( 588.466)m3 YT=( .246)m3 G=( 3.6)V N=(X0000000000) M=(Y0000000000) O=(Z0000000000) Date=(06.01.01)Time=(00:54:55) Q=( .00)m3/hr
XD=(111 ) XT=( 588.466)m3 YT=( .009)m3 G=( 3.6)V N=(X0000000000) M=(Y0000000000) O=(Z0000000000) Date=(06.01.01)Time=(00:54:55) Q=( .00)m3/hr
The specific requirement is that I need all the values from the above given string which is a collection of key/value pairs. Also, would like to know the right approach (in terms of efficiency and performance) out of the two...Regex pattern matching or substring, for the above problem.
Thank you all in advance and let me know, if more details are required.
I don't know C#, so there probably is a better way to build a key/value array. I constructed a regex and handed it to RegexBuddy which generated the following code snippet:
StringCollection keyList = new StringCollection();
StringCollection valueList = new StringCollection();
StringCollection unitList = new StringCollection();
try {
Regex regexObj = new Regex(
#"(?<key>\b\w+) # Match an alphanumeric identifier
\s*=\s* # Match a = (optionally surrounded by whitespace)
\( # Match a (
\s* # Match optional whitespace
(?<value>[^()]+) # Match the value string (anything except parens)
\) # Match a )
(?<unit>[^\s=]+ # Match an optional unit (anything except = or space)
\b # which must end at a word boundary
(?!\s*=) # and not be an identifier (i. e. followed by =)
)? # and is optional, as mentioned.",
RegexOptions.IgnorePatternWhitespace);
Match matchResult = regexObj.Match(subjectString);
while (matchResult.Success) {
keyList.Add(matchResult.Groups["key"].Value);
valueList.Add(matchResult.Groups["value"].Value);
unitList.Add(matchResult.Groups["unit"].Value);
matchResult = matchResult.NextMatch();
}
Regex re=new Regex(#"(\w+)\=\(([\d\s\.]+)\)");
MatchCollection m=re.Matches(s);
m[0].Groups will have { XD=(111111), XD, 111111 }
m[1].Groups will have { XT=( 588.466), XT, 588.466 }
String[] rows = { "XD=(111111) XT=( 588.466)m3 YT=( .246)m3 G=( 3.6)V N=(X0000000000) M=(Y0000000000) O=(Z0000000000) Date=(06.01.01)Time=(00:54:55) Q=( .00)m3/hr",
"XD=(111 ) XT=( 588.466)m3 YT=( .009)m3 G=( 3.6)V N=(X0000000000) M=(Y0000000000) O=(Z0000000000) Date=(06.01.01)Time=(00:54:55) Q=( .00)m3/hr" };
foreach (String s in rows) {
MatchCollection Pair = Regex.Matches(s, #"
(\S+) # Match all non-whitespace before the = and store it in group 1
= # Match the =
(\([^)]+\S+) # Match the part in brackets and following non-whitespace after the = and store it in group 2
", RegexOptions.IgnorePatternWhitespace);
foreach (Match item in Pair) {
Console.WriteLine(item.Groups[1] + " => " + item.Groups[2]);
}
Console.WriteLine();
}
Console.ReadLine();
If you want to extract the units also then use this regex
#"(\S+)=(\([^)]+(\S+))
I added a set of brackets around it, then you will find the unit in item.Groups[3]