I'm really struggling to get a regex working. All I want to do is something that would capture a string and its trailing space and put that as an entry into an array.
For example:
"RegExr #was created by gskinner.com, and is proudly hosted by Media Temple.
Edit the Expression & Text to see matches."
["RegExr ", "#was ", "created ", "by ", gskinner.com " ... "& " ... "matches. " etc...]
I'm trying to do the following in a React App:
console.log("matches are: ", message.match(/(\w+\s|#\w+\s|\s )/));
return message.match(/((\w+ ?))/);
// return message.split(" ");
I found that the split function was created some weird issues for me so I wanted just to have the matches function return an array of the results I specified above.
When I log out some attempts I just get weird results no matter what I try, like this:
e.g.
matches are: (2) ["Hey ", "Hey ", index: 0, input: "Hey Martin Im not sure how to make the font in this box bigger #ZX81", groups: undefined]
Can someone help it is really blocking some progress on my app.
To get all non-whitespace char chunks with any adjoining whitespace, you can use
message.match(/\s*\S+\s*/g)
See the regex demo. The g flag will make it extract all matches of
\s* - zero or more whitespace chars
\S+ - one or more non-whitespace chars
\s* - zero or more whitespace chars.
See a JavaScript demo:
const message = "RegExr #was created by gskinner.com, and is proudly hosted by Media Temple. Edit the Expression & Text to see matches.";
console.log(message.match(/\s*\S+\s*/g));
Related
I've been gathering information using api calls from my jira. Information gathered is saved in a body file and it has the following content:
No tickets:
{"startAt":0,"maxResults":50,"total":0,"issues":[]}{"startAt":0,"maxResults":50,"total":0,"issues":[]}
One Ticket:
{"expand":"names,schema","startAt":0,"maxResults":50,"total":1,"issues":[{"expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields","id":"456881","self":"https://myjira...com","key":"TICKET-1111","fields":{"summary":"[TICKET] New Test jira","created":"2018-12-17T01:47:09.000-0800"}}]}{"expand":"names,schema","startAt":0,"maxResults":50,"total":1,"issues":[{"expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields","id":"456881","self":"https://myjira...com","key":"TICKET-1111","fields":{"summary":"[TICKET] New Test jira","created":"2018-12-17T01:47:09.000-0800"}}]}
Two Tickets:
{expand:schema,names,startAt:0,maxResults:50,total:2,issues:[{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:456881,self:https://myjira...com,key:TICKET-1111,fields:{summary:[TICKET] New Test jira,created:2018-12-17T01:47:09.000-0800}},{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:320281,self:https://myjira...com,key:TICKET-2222,fields:{summary:[TICKET] Test jira,created:2016-03-18T07:58:52.000-0700}}]}{expand:schema,names,startAt:0,maxResults:50,total:2,issues:[{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:456881,self:https://myjira...com,key:TICKET-1111,fields:{summary:[TICKET] New Test jira,created:2018-12-17T01:47:09.000-0800}},{expand:operations,versionedRepresentations,editmeta,changelog,renderedFields,id:320281,self:https://myjira...com,key:TICKET-2222,fields:{summary:[TICKET] Test jira,created:2016-03-18T07:58:52.000-0700}}]}
etc..
Using this code I've been able to gather total open tickets:
std::ifstream t("BodyOpenIssues.out");
std::string BodyString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
// Removing Quotes
BodyString.erase(std::remove(BodyString.begin(), BodyString.end(), '"'), BodyString.end());
int Result = 0;
unsigned first = BodyString.find("total:");
unsigned last = BodyString.find(",issues");
std::string TotalOpenIssues = BodyString.substr(first + 6, last - (first + 6));
Result = std::stoi(TotalOpenIssues);
return Result;
Using a second function I'm trying to get the keys based on total open tickets.
if (GetOpenIssuesNumber() > 0)
{
std::ifstream t("BodyOpenIssues.out");
std::string BodyString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
// Removing Quotes
BodyString.erase(std::remove(BodyString.begin(), BodyString.end(), '"'), BodyString.end());
unsigned first = BodyString.find("key:TICKET-");
unsigned last = BodyString.find(",fields");
std::string TotalOpenIssues = BodyString.substr(first + 11, last - (first + 11));
String^ Result = gcnew String(TotalOpenIssues.c_str());
return "TICKET-" + Result;
}
else
{
return "No open issues found";
}
What I mean is:
If Total is 1 to search from the beginning and find the first key TICKET-1111.
If Total is 2 to search from the beginning and get the first key TICKET-1111 then to continue from there and to find the next key TICKET-2222.
And based on that total to find that many keys in that string.
I got lost from all the casting between the types as ifstream reads the file and I save the result in std::string. After the find I save the result in System::String to use it in my Label.. I've been researching and found out that I can use char array but I can't make it dynamic based on BodyString.length().
If more information is required please let me know.
Any suggestions are really appreciated! Thank you in advance!
I went for nlohmann json library. It has everything I need. Thank you Walnut!
These are formatted as JSON. You should use a JSON library for C++ and parse the files with that. Using search/replace is unnecessary complicated and you will likely run into corner cases you haven't considered sooner or later (do you really want the code to randomly miss tickets, etc.?). Also String^ is not C++. Are you writing C++/CLI instead of C++? If so, please tag c++-cli instead of c++. – walnut
I am attempting to add a search feature to Quill and want to highlight the text that it finds. I am having trouble getting the range index for the text it finds, and it is likely that I am not using the correct approach.
So far, I get the text using getContents() and can find matches by iterating through the lines. However, I have not been able to find the correct index position for setSelection(). A second issue is that I want the window to scroll to where the selection is found, and it is not scrolling into view.
...
myKeyPhrases = ['obvious', 'orange', 'apple'];
var myDelta = editor.getContents();
myDelta.eachLine((line, attributes, i) => {
mytext = line.filter((op) => typeof op.insert === 'string').map((op) => op.insert).join('');
mytext = mytext.toLowerCase();
ndx = isKeyPhraseFound(mytext, myKeyPhrases);
if (ndx >= 0){
// The code finds the matches OK to here.
// The next 4 lines don't get the correct range and scroll.
index = i;
editor.focus();
editor.setSelection(index, 1, Quill.sources.USER);
editor.scrollIntoView();
return index;
}
});
My desired results would be that a found text match would be selected and that the window would be scrolled so that the selection is displayed. The actual results are that the wrong text is selected and the window is not scrolled to view the selection.
You're basically there. I suspect your issue is that you're filtering out block elements, which acts similarly to Quill's getText method. According to the docs:
Non-string content are omitted, so the returned string’s length may be shorter than the editor’s as returned by getLength.
This is because non-text elements usually have a length of 1, so for every one of those you omit, your index will drift by 1.
A simple workaround for this is to replace any non-text elements with a newline character, which has length 1, and the added benefit of causing a search across it to fail (unless you let users search with newlines - maybe then you can pick another special character like a control character).
The following method should return a plain-text representation of your Quill contents whose length matches quill.getLength, and therefore should be able to be searched using whatever JavaScript text search method you want (eg indexOf for simple searches).
function textContents() {
return quill.getContents().ops
.reduce((text, op) => {
if (typeof op.insert === 'string') {
// If the op is a string insertion, just concat
return text + op.insert;
} else {
// Otherwise it's a block. Represent this as a newline,
// which will preserve the length of 1, and also prevent
// searches matching across the block
return text + '\n';
}
}, '');
}
Here's a rough example: https://codepen.io/alecgibson/pen/GLVzPb
I'm trying to adapt KG4SGP's RTTY modulator to send a textfile instead of a fixed char array. I'm getting Strings by the readLine() method, altering these Strings by replacing certain values and then copy the altered String to a charArray.
I changed his globalchar msg[] = "\n\nCQ CQ CQ DE KG4SGP KG4SGP KG4SGP KN\n\n"; tochar msg[70]; and hoped to have this running instead;
while(text.available()) {
String lin= readLine();
lin.toLowerCase();
if (lin.indexOf("&")) {
if (lin.indexOf("&de ")) {
lin.replace("&de ", "de ");
result = calculateDayOfYear(dag,maand,jaar);
lin.replace("juldate" , String(result));
lin.replace("hour", String(uur));
lin.replace("min", String(mins));
}
if (lin.indexOf("month")) {
lin.replace("&","");
lin.replace("day", String(dag));
lin.replace("hour", String(uur));
rmin=random(1, mins);
lin.replace("rndmin", String(rmin));
lin.replace("month", (months[maand-1]));
lin.replace("year", kortjaar );
}
lin.toUpperCase();
lin.toCharArray(msg,lin.length()+1);
//Serial.println(msg);
}
Well, whatever I did or tried, I'm never getting any charArray to correctly identify the current character and translate it.. :-( It seems to all come out of the timerfunction
All suggestions welcome
Is it possible to concatenate using lr_save_string?
sortoption,next and basket, bookIDs_array are all correctly assigned values.
Code
lr_save_string(lr_eval_string("sortoption={sortoption}&next={next}&basket={basket}"), "BodyString");
for (i=1; i<=lr_paramarr_len("BookIDS_array"); i++) {
lr_save_string(lr_paramarr_idx("BookIDS_array", i), "BookID");
lr_save_string(lr_eval_string("{BodyString}&bookId%5B%5D%3D{BookID}"), "BodyString");
}
lr_output_message("Value: %s", lr_eval_string("{BodyString}"));
However the above seems to just assign the below to BodyString
sortoption={sortoption}&next={next}&basket={basket}
You may want to consider this other thread for a concatenation example in LoadRunner
How to change input soap request as per test data in loadrunner?
I took a look at the XML link and it's very similar to what I wanted to do, but I had some json to update if there was a value. My approach to the issue below:
//Define the object to store.
char ifPhoneThenAdd[100];
...
...
...
//Capture the full part of the address information of the first entry including city, phone, etc. - In my scenario, all I need is the first one from the json response..
web_reg_save_param_json("ParamName=AddressData","QueryString=$.Addresses","SelectAll=No",SEARCH_FILTERS,"Scope=Body",LAST);
...
...
...
web_rest("......",
"URL={App_URL}/details/{userID}",
"Method=GET",
"Snapshot=t999990.inf",
LAST);
...
...
...
//Some explanation of the json output:
//A sample of the json output would look something like this (from the output tab):
//Saving Parameter "AddressData" = [{"Id":"xxxxxxxxxxx","city":"Calgary","street":"123 Santas Workshop","postalCode":"H0H 0H0","country":"CA","region":"AB","email":"baba#oriley.com","phone":"403xxxxxxx"}]"
//Without the phone, it would be:
//[{"Id":"xxxxxxxxxxx","city":"Calgary","street":"123 Santas Workshop","postalCode":"H0H 0H0","country":"CA","region":"AB","email":"baba#oriley.com"}]"
//This part changes the body in case there is a phone number and does not include phone number if there is none in the reply.
sprintf(ifPhoneThenAdd,"");
if (strstr(lr_eval_string("{AddressData}"), "\"phone\"") != NULL)
{
lr_eval_json("Buffer={AddressData}", "JsonObject=json_obj", LAST);
lr_json_get_values("JsonObject=json_obj", "ValueParam=AddressWithPhoneNumber", "QueryString=$..phone", "SelectAll=No", LAST);
sprintf(ifPhoneThenAdd,"%s%s%s",",\r\n\"phoneNumber\":\"",lr_eval_string("{AddressWithPhoneNumber}"),"\"");
}
else
{
//Doesn't make the script fail, but will send an error message.
lr_error_message("No phone number for ID: %s", lr_eval_string("{userID}"));
}
lr_save_string(ifPhoneThenAdd, "ifPhoneThenAddString");
//If there is no phone, then the string ifPhoneThenAddString will be empty and nothing but the empty string will be added to the json output.
//If there is a phone, then the body will get appended with the right json output with the phone number.
...
...
...
web_rest("......",
"URL={App_URL}/updateSomethingNeedingAddress/{userID}",
"Method=POST",
"EncType=raw",
"Snapshot=t999991.inf",
"Body={\r\n"
"\"Id\":\"{userID}\",\r\n"
"\"firstName\":\"{userFirstname}\",\r\n"
"\"lastName\":\"{userLastname}\",\r\n"
"\"streetName\":\"{userStreetName}\",\r\n"
"\"city\":\"{userCity}\",\r\n"
"\"province\":\"{userProvince}\",\r\n"
//This part will add the phone part if there is one after the postalCode. If no phone, the postalCode will be the last part of the json.
"\"postalCode\":\"{userPostalCode}\"{ifPhoneThenAddString}\r\n"
"}",
HEADERS,
"Name=Content-Type", "Value=application/json", ENDHEADER,
LAST);
...
...
...
return 0;
I have written the code to check the query string
Logic::if query string is "?" should remove all the characters from the query string and print the vailid URL.
char str[] = "http://john.org/test.mp4?iufjdlwle";
char *pch;
pch = strtok(str,"?");
printf("%s\n",pch);
Output::
bash-3.2$ ./querystring
http://john.com/test.mp4
But i have to check one more case
Need to get the URL only if there is any extensions present before query string?
if No extensions are present before the query string,need to skip.
I have tried this way,
continuation of the code
char *final;
final = pch+(strlen(pch)-3);
printf("%s\n",final);
if(strcasecmp(p,"mp4"))
printf("falure case\n");
else
printf("Success case\n");
It will work for .mp4 extension alone.
Incase if i'm getting *.mpeg or *.m3u8 or *.flv as an extensions,it will fail.
Can someone guide me how to solve this problem and make it working?
A query string is what starts after a question mark ?, fine.
You should try to define what an extension is. For me, it is what can happen after a dot (.) in the last component of the url, where the components are delimited with slashes (/)
So you should do:
first remove the possible query string including the initial ?
then locate the last /
then locate the last . that occurs after the last /
If you find one, it is the starting point of the extension.
So assuming pch contains the url without any query string, you can do:
char * ix = strrchr(pch, '/');
if (ix == NULL) {
// an URL without / is rather weird, better report and abort
...
}
ix = strrchr(ix, '.');
if (ix == NULL) {
// no extension here: ignore the url
...
}
else {
// found an URL containing an extension: process it
// ix+1 points to the extension
...
}