I'm trying to write a regex that matches any semicolon symbol ; that doesn't start with !important or !important
For instance, if I have the following string:
.myclass {
width: 400px;
color: #333;
margin: 20px !important;
padding: 20px !important ;
top: 1px;
}
I want to match those lines:
width: 400px;
color: #333;
top: 1px;
So I can then run replace on them and add the !important attribute to them.
How should I write the regex that would match this?
Try using this one: (?!.*!important).*;.
Breaking it down into smaller pieces we are using a negative lookahead (?!<pattern>) to say we want to match where there is NOT the match later in the string. After that, we just need to look for any chars up until we see a closing ;. The way the negative lookahead is setup, if the line is ending in the ; and there is a match to !important at all it will fail, no matter how many spaces are inbetween. Since CSS can have spaces, this handles a lot more cases you could see other then 0 or 1 spaces.
If you wanted it to be EXACTLY like the original post where you are checking for zero or one space after !important but before ;, you can change the lookahead to include \s?;, after !important of course. This is checking for ANY whitespace, zero or one of, followed directly by the ;.
This one worked for me at a Regex tester:
.+[^((?!important)\s];
The regex matches any number of characters (.+) except the ones with !important in it ([^!important]).
If this is entirely in one string variable
.myclass {
width: 400px;
color: #333;
margin: 20px !important;
padding: 20px !important ;
top: 1px;
}
then you can split it on the new-line:
String[] lines = input.split(System.getProperty("line.separator", "\r\n"));
Then, skipping the first and last elements (which contain the curly-braces), only get lines that do not match "!important ?;"
Matcher importantMtchr = Pattern.compile("!important ?;").matcher("");
for(int i = 1; i < lines.length - 1; i++) {
String line = lines[i];
if(!importantMtchr.reset(line).find()) {
System.out.println(line);
}
}
Full code:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class NotExclamationImportantLines {
public static final String LINE_SEP = System.getProperty("line.separator", "\r\n");
public static final void main(String[] ignored) {
String input = new StringBuilder().
append("myclass {" ).append(LINE_SEP).
append("width: 400px;" ).append(LINE_SEP).
append("color: #333;" ).append(LINE_SEP).
append("margin: 20px !important;" ).append(LINE_SEP).
append("padding: 20px !important ;").append(LINE_SEP).
append("top: 1px;" ).append(LINE_SEP).
append("}" ).toString();
//Split on the newline
String[] lines = input.split(LINE_SEP);
//Skip over the first and last elements, and only
//print out those that don't contain the regular
//expression `"important! ?"
Matcher importantMtchr = Pattern.compile("!important ?;").matcher("");
for(int i = 1; i < lines.length - 1; i++) {
String line = lines[i];
if(!importantMtchr.reset(line).find()) {
System.out.println(line);
}
}
}
}
Output:
width: 400px;
color: #333;
top: 1px;
^(?!.*!important\s*;).*?(;)\s*$
^^^^^^^^^^^^^^^^ ^
(1) (2)
Negative Lookahead assertion: Find lines that do not contain !important followed by zero or more whitespace characters followed by a semicolon.
Capture Group: In the lines that pass the negative-lookahead test, capture only a semicolon at the end that is followed by zero or more whitespace characters.
See the live demo.
Related
Use Regex to highlight all text between two parentheses but not a specific word
ex:
"This is a << long text used just as an example to test >> how I can use Regex"
There are words between << >> I need to have two different styles, one for any text between <<>> and another one for only the bold text: example
"long text.......to test" will be in RED
ONLY "simple" will be in GREEN
any other words which outside the parentheses will be in Black
I'm using flutter_parsed_text package
ParsedText(
text: widget.text, \\The main text which to be parsed with regex
style: TextStyle(color: Colors.black), \\defult style if none is matching
parse: [
//1st pattern match anything between <<>>
MatchText(
pattern: "\<<(.*?)\>>", // " << everything but not $searchKeyword >> "
style: TextStyle(color: ColorsUtils.red),
),
//2nd pattern match the searchKeyword which in not selected in any pattern
MatchText(
pattern: '$searchKeyword',
style: TextStyle(color: Colors.green),
)
],
);
I fetched data from a web sites body.Then I write a regular expression and applied on DART but it didnt work.What is the Problem?
Here is the Regex code:
</td><td align="left">(.*?)</td><td class="dataGridActive
Here is my part of the content:
</tr><tr onmouseover="mover(this);" onmouseout="mout(this);" style="background-color:White;">
<td align="left">233</td><td align="left">ÖMER EFE CIKIT</td><td class="dataGridActive" align="center">
And the dart code:
void CheckRE(String text) {
final RegExp pattern = RegExp(
r'</td><td align="left">(.*?)</td><td class="dataGridActive"',
multiLine: true,
caseSensitive: true,
); // 800 is the size of each chun
pattern
.allMatches(text)
.forEach((RegExpMatch match) => print(match.group(1)));
}
I think what you want is the following.
I have changed your output so it prints the content of capture group 1 instead of capture group 0. Capture group 0 contains the whole string which matches while 1 and up contains the content of each defined capture group in your regular expression.
const input = '''
</tr><tr onmouseover="mover(this);" onmouseout="mout(this);" style="background-color:White;">
<td align="left">233</td><td align="left">ÖMER EFE CIKIT</td><td class="dataGridActive" align="center">
''';
void main() => checkRE(input); // ÖMER EFE CIKIT
void checkRE(String text) {
final RegExp pattern = RegExp(
r'</td><td align="left">(.*?)</td><td class="dataGridActive"',
multiLine: true,
caseSensitive: true,
); // 800 is the size of each chun
pattern.allMatches(text).forEach((RegExpMatch match) => print(match[1]));
}
Also changed (.*) to (.*?) based on advice from #MikeM.
I have a text field that returns a string of characters from 38 to 40 long. I need to just extract from the 30th character to the end.
I used .{9}$ to grab the last nine, then realized that the original strings are not a set amount of characters and only the first 29 is not needed. Everything after is the case number and is what I need. Again the number of characters needed can be anywhere from 9 to 12 long
Skip the First 29 and Extract the Rest
Here are string methods .slice(), .substring(), and .replace(). A RegEx that'll skip the first 29 characters and spaces then extract the rest is:
(?:[\s\S]{29})([\s\S]*?)
Start matching non-capture: (?:...
Any space or non-space character: [\s\S]
Twenty-nine times: {29}
End matching non-capture: ..)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Next, start matching capture: (...
Any space or non-space character: [\s\S]
Zero or more times: *
Lazily: ?
End matching capture: ...)
Demo
var str = '123456789㉈123456789㉉123456789㉊123456789㉋';
var rgx = /(?:[\s\S]{29})([\s\S]*?)/;
console.log('var str = ' + str);
console.log('--------------------------------------------------');
console.log('str.slice(29) // ' + str.slice(29));
console.log('--------------------------------------------------');
console.log('str.substring(29) // ' + str.substring(29));
console.log('--------------------------------------------------');
console.log(`var rgx = ${rgx}`);
console.log('str.replace(rgx, "$1") // ' + str.replace(rgx, '$1'));
.as-console-wrapper {
min-height: 100%;
}
.as-console-row-code.as-console-row-code {
font-size: 18px;
}
.as-console-row.as-console-row::after {
display: none;
}
you can use substring function
[YourString].substring(29)
When using Python, simply do:
string[30:]
This will automatically return the thirtiest character to the end.
^.{30}\K.*$
^ asserts position at start of the string
.{30} Quantifier — Matches exactly 30 times
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match
.* matches any character (except for line terminators)
$ asserts position at the end of the string, or before the line terminator right at the end of the string (if any)
Here is the string I want to match 76c24efd-ec42-492a-92df-c62cfd4540a3. The following regex will match a 36 char length string with alphanumeric characters and '-'.
[a-zA-Z0-9\-]{36}
I am trying to add to this regex, so it matches only when <8 chars> - <4 chars> - <4 chars> - <4 chars> - <12 chars>
The following will match a group of 8 characters followed by a dash, then a group of 4 characters followed by a dash 3 times, and then a group of 12 characters.
^[a-z0-9]{8}-(?:[a-z0-9]{4}-){3}[a-z0-9]{12}$/
Here's a short JavaScript test that shows the results.
$('.test').each(function(row, item) {
var val = $($(item).children()[0]).html()
var result = /^[a-z0-9]{8}-(?:[a-z0-9]{4}-){3}[a-z0-9]{12}$/gi.test(val);
$($(item).children()[1]).html(result.toString())
});
th {
text-align:left;
padding-right:10px;
}
td {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="border: 1px solid black">
<tr><th>Test</th><th>Result</th><th>Desired Result</th></tr>
<tr class="test"><td>76c24efd-ec42-492a-92df-c62cfd4540a3</td><td></td><td>Good</td></tr>
<tr class="test"><td>76c24efd-ecz42-492a-92df-c62cfd4540a3</td><td></td><td>Bad Length - 2nd segment too long</td></tr>
<tr class="test"><td>76c24efd-ec2-492a-92df-c62cfd4540a31</td><td></td><td>Bad Segment Lengths</td></tr>
<tr class="test"><td>76$24efd-ec42-492a-92df-c62cfd4540a3</td><td></td><td>Bad Char ($)</td></tr>
</table>
I'm using this Regex:
padding:(\s*(\d+px\s*|0\s*)){4}
to find padding style's with four values in Visual Studio "Find And Replace".
Now I want to replace the second value with fourth like this:
padding: 1px 0 3px 4px;
padding: 1px 2px 0 4px;
padding: 1px 2px 3px 0;
change this values to:
padding: 1px 4px 3px 0;
padding: 1px 4px 0 2px;
padding: 1px 0 3px 2px;
is there a way I can replace them with the "Find And Replace" dialog?
Note that (\s*(\d+px\s*|0\s*)){4} captures the (\s*(\d+px\s*|0\s*)) subpattern 4 times, and the captures are stored in the CaptureCollection that can only be retrieved with .NET code. In a search and replace feature, you can only access groups with backreferences.
You can use:
Find: (padding:\s*)(\d+(?:px)?)\s*(\d+(?:px)?)\s*(\d+(?:px)?)\s*(\d+(?:px)?);
Replace: $1$2 $5 $4 $3
See demo
Results:
padding: 1px 4px 3px 0
padding: 1px 4px 0 2px
padding: 1px 0 3px 2px
Note I decided to hard-code the whitespaces in the replacement, but you can also set capturing groups round \s* to replicate them in the resulting string.
Regex breakdown:
(padding:\s*) - Group 1 matching padding: plus 0 or more whitespace
(\d+(?:px)?) - Group 2 matching 1 or more digits (\d+) and optionally px
\s* - 0 or more whitespaces
(\d+(?:px)?)\s*(\d+(?:px)?)\s*(\d+(?:px)?) - 3 more capturing groups with indices 3, 4, 5
; - a literal semi-colon.