I would like to assert in Protractor that a link text is composed by the following way: text-1 (where text is a variable, and the number can be composed by any digits).
I tried the following:
browser.wait(
ExpectedConditions.visibilityOf(
element(by.xpath(`//a[#class = 'collapsed' and starts-with(text(), '${text}') and ends-with(text(), '-(/d+)')]`))),
5000)
and
browser.wait(
ExpectedConditions.visibilityOf(
element(by.xpath(`//a[#class = 'collapsed' and starts-with(text(), '${text}') and ends-with(text(), '/^-(/d+)$/')]`))),
5000)
Unfortunately, none of the above xpaths worked.
How can I fix this?
If you change the way to declare the variable and your second predicate you can go with :
//a[#class='collapsed'][starts-with(text(),'" + text_variable + "')][number(replace(.,'^.*-(\d+)$','$1'))*0=0]
where [number(replace(.,'^.*-(\d+)$','$1'))*0=0] test for the presence of a number at the end of a string.
Example. If you have :
<p>
<a class="collapsed">foofighters-200</a>
<a class="collapsed">foofighters</a>
<a class="collapsed">boofighters-200</a>
<a class="collapsed">boofighters-200abc</a>
</p>
The following XPath :
//a[#class='collapsed'][starts-with(text(),'foo')][number(replace(.,'^.*-(\d+)$','$1'))*0=0]
will output 1 element :
<a class="collapsed">foofighters-200</a>
So in Protractor you could have :
var text = "foo";
browser.wait(ExpectedConditions.visibilityOf(element(by.xpath("//a[#class='collapsed'][starts-with(text(),'" + text + "')][number(replace(.,'^.*-(\d+)$','$1'))*0=0]"))), 5000);
...
You can use regexp for this:
await browser.wait(async () => {
return new RegExp('^.*(\d+)').test(await $('a.collapsed').getText());
}, 20000, 'Expected link text to contain number at the end');
Tune this regex here if needed:
https://regex101.com/r/9d9yaJ/1
Related
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'm trying to format user input in vue.js. The input is representing time mm.ss. Two numbers then dot and two numbers again. The dot should appear automatically after first two number are typed. I was able to achieve it using rexeg here's the codepen:
https://codepen.io/Marek92/pen/KKKqKjx
<div id="app">
<h1>{{ title }}</h1>
<input type="text" v-model="performance">
</div>
new Vue({
el: '#app',
data: {
title: 'Input formating!',
performance: '12.00'
},
watch: {
performance() {
this.performance = this.performance.replace(/[^0-9]/g, '')
.replace(/^(\d{2})(\d{2})?/g, '$1.$2')
.substr(0, 5);
}
}
});
However the problem is when the input is there. Let's say '12.00' and you start deleting the number using backspace from the end. You get stuck on the dot. Unable to delete the dot and that is my problem. How can I change the regex to be able delete the dot? Or some other solution?
Please look at below code-
new Vue({
el: '#app',
data: {
title: 'Input formating!',
performance: '12.00'
},
watch: {
performance() {
var a = this.performance.replace(/[^0-9]/g, '')
.substr(0, 5);
if (a.length >= 3) {
a = a.substring(0, 2) + '.' + a.substring(2, a.length)
}
this.performance =a;
}
}
});
Explanation: Try to add a point after 2 digit when there is more than 2 digits. otherwise remove all characters except digits.
https://codepen.io/ashfaq_haq/pen/xxxrbYO
I had ESLint build rules in place that were not allow me to use Regex. If you have the same issue simply removed the rules by configuring the eslintrc.js file
'rules': {
// allow regex test of phone numbers
'no-useless-escape': 0
}
and then you can create the const and use the test method. worked great for my phone number check.
const phoneNumberFormat =
new RegExp(/^[+]?(\d{1,2})?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/)
const validatePhoneNumber = (context, event) => {
let address = context.address
if (!phoneNumberFormat.test(address.phoneNumber)) {
return false
}
return true
}
Your second capture group is optional, so it will try to add the . when you delete it because a two digit number also matches the regex. One option is to remove the optional syntax ?, use /^(\d{2})(\d{2})/g or /^(\d{2})(\d{1,2})/g so that it only starts to format when there are more than two numbers.
See https://codepen.io/leopsidom/pen/zYYzxKY.
I want to replace all matched strings after regExp with same strings in span elements. Is this possible?
I want to do something like that:
final text = message.replaceAllMapped(exp, (match) => '<span>exp, (match)</span>');
You may use String#replaceAllMapped like this:
final exp = new RegExp(r'\d+(?:\.\d+)?');
String message = 'test 40.40 test 20.20';
final text = message.replaceAllMapped(exp,
(Match m) => "<span>${m[0]}</span>");
print(text);
Output: test <span>40.40</span> test <span>20.20</span>
Here, m is the Match object that the regex engine finds and passes to the arrow method where the first item in the m array is inserted in between <span> and </span> inside an interpolated double quoted string literal.
I'm trying to do a monthly installment with some possibilities, like:
3x // result == 3
10x // result == 10
30 // result == 1
30./60 // result == 2
30#60#90 // result == 3
30 60 90 120 // result == 4
30-60- 90-120--150 // result == 5
30x60x90x120x150x180 // result == 6
and so on... I'm trying to get any character, with multiple spaces OR multiple characters (equals to each other or not). I reach the following code so far... but I could add the exception for numbers, and the result are not always right.
var pattern = /(\#?[a-zA-Z(!0-9) \/]+)/g;
var a = '30/60/90';
var b = a.split(pattern);
$('#yyy').text(b);
$('#xxx').text(b.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label id="yyy"></label>
<br><br>
<label id="xxx"></label>
I'm HORRIBLE in regex, really "noob" to it, so if could explain in the answer/comment WHY you are doing specific regex, I would be please (so I can learn instead of copy/paste without too much clue)
I'm not so sure I understood your question correctly, but I'll answer as I understood it:
To split on anything except numbers, the solution would be:
var pattern = /\D+/g;
var a = '30/60/90';
var b = a.split(pattern);
$('#yyy').text(JSON.stringify(b));
$('#xxx').text(b.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label id="yyy"></label>
<br><br>
<label id="xxx"></label>
The regex is pretty simple: \d means a digit, so \D means not a digit, so \D+ means a series of characters that are not digits.
It may be even easier if you try matching instead of splitting:
var pattern = /\d+/g;
var a = '30/60/90';
var b = [];
var m;
while (m = pattern.exec(a))
b.push(m[0]);
$('#yyy').text(JSON.stringify(b));
$('#xxx').text(b.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label id="yyy"></label>
<br><br>
<label id="xxx"></label>
In that case \d+ means a series of digits.
For reference, in JS:
\d is shorthand for [0-9]
\D is shorthand for [^0-9]
This question already has answers here:
RegEx match open tags except XHTML self-contained tags
(35 answers)
Closed 9 years ago.
I have a QString of rich text more or less in this format:
<span background-color="red"><a name='item1'></a> property1 </span> + <span background-color="blue"><a name='item2'></a> property2 </span>
It can have more tags, but all will have the same structure. Also, between each tag, operators will show up - this is a string that is supposed to represent a calculation.
I need a regex to traverse the string and extract both the item1, item2, ...; but also the property1, property2,... substrings so I can then retrieve a value which I have stored somewhere else.
Then, after retrieving these values, and if, for example, property1=value1 and property2=value2 , I need to create another string like:
value1 + value2
This string will be evaluated to compute the calculation.
What would be the regex to read the string?
What would be the regex to replace in a copied string?
NOTE I do not intend to parse HTML with these regexps. The string of rich-text I need to filter has at most the tags and structure represented above. It will not have other types of tags, nor will it have other attributes besides the ones in the example string above. It can only have more examples of that same tag structure: a span, containing an anchor tag with a name attribute and some text to display.
NOTE2 #Passerby posted in the comments of this question a link to a very aproximate solution. I forgot one (hopefully small) detail about my objective: I also need to catch whatever is between the span tags as a string as well, instead of simply checking for a char like #Passerby (very well) suggested. Any ideas?
NOTE3 I actually still argue that this is not the same question as the duplicate marked one. While the strings I am filtering look like HTML, they are actually rich-text. They will always have this rigid structure/format, so RegEx is perfectly viable for what I need to do. After some great comments I got from a few users, namely #Passerby, I decided to go for it and this works perfectly for what I need:
Sample string:
<span background-color="red"><a name='item1'></a> property1 </span> + 300 * <span background-color="blue"><a name='item2'></a> property2 </span> + Math.sqrt(<span background-color="green"><a name='item3'></a> property3 </span>)
Regex:
/ <span.*?><a name='(.*?)'><\/a>\s*(.*?)\s*<\/span>(((.*?)?)(?=<)|) / g
Outputs:
MATCH 1
1. [38-43] `item1`
2. [50-59] `property1`
3. [67-76] ` + 300 * `
4. [67-76] ` + 300 * `
5. [67-76] ` + 300 * `
MATCH 2
1. [115-120] `item2`
2. [127-136] `property2`
3. [144-157] ` + Math.sqrt(`
4. [144-157] ` + Math.sqrt(`
5. [144-157] ` + Math.sqrt(`
MATCH 3
1. [197-202] `item3`
2. [209-218] `property3`
3. [226-226] (null, matches any position)
This would be probably something like:
QRegExp rx("^(?:\\<span background-color=\"red\"\\>\\<a name=')(\\w)(?:'\\>\\</a\\>)\s*(\\d+)\s*(?:\\</span\\>)\s*(\+)\s*(?:\\<span background-color=\"blue\"\\>\\<a name=')(\\w)(?'\\>\\</a\\>)\")\\s*(\\d+)\\s*\\</span\\>)$");
rx.IndexIn(myText);
qDebug() << rx.cap(1) << rx.cap(2) << rx.cap(3) << rx.cap(4) << rx.cap(5);
//will return item1 prop1 + item2 prop2
given item would be one word and property would be a number. I did something very similar in a calculator for our software.
The trick is, start with small bits:
rx("\\<a name='\\w'\\>");
which would capture the item but eventually the complete line. Then go for next bit and keep it on until you got the whole line like you want it to be.
Regular Expressions can be very powerfull but also very frustrating.
Good luck
Edit: Every bracket () can be accessed via \1 in replace function. (?:) brackets are not captured! So :
QString text = "My Text";
text.replace("^My( Text)$","His\\1");
//will have returned: His Text
I don't understand regexps either. With this kind of parsing problem I would use quick and (maybe) dirty solution like this:
QString str = "<span background-color='red'><a name='item1'></a> property1 </span> + <span background-color='blue'><a name='item2'></a> property2 </span>";
QStringList slist = str.split("<");
qDebug() << slist;
foreach (QString s, slist)
{
if (s.startsWith("/a"))
{
qDebug() << "property:" << s.split(" ")[1];
}
else if (s.startsWith("a name"))
{
qDebug() << "item:" << s.split("'")[1];
}
else if (s.startsWith("/span>"))
{
QString op = s.mid(6).trimmed();
if (op != "")
qDebug() << "operator:" << op;
}
}
And output is:
item: "item1"
property: "property1"
operator: "+"
item: "item2"
property: "property2"
Of course, this will break down if the format changes. But so will the regexp too.
If the format would be any more complicated I would try to change the format to valid XML and then using Qt's XML classes to parse the data.
If you end up using this kind of solution, I really recommend adding some additonal validity checks.