I have an assignment for a class where I have to read in the name of an item, it's weight, and then price. How do I create a while loop to store each individual element into a string, and two doubles respectively?
Example from text file:
Bananas
1.31
0.99
Rib Eye Steak
2.55
14.96
Chicken Breast Value Pack
7.85
21.97
Dry Dog Food
20.00
14.99
Apples
2.50
3.49
you can do a for loop that goes to the next character and it puts it into a variable until it hits a space and when that happens it puts that into a array until it's done. and you can do everything you want to that and after that I don't know anything c++ but that's it.
var out1 = "";
var out = [];
for (var i =0; i<(the-file).length; i++) {if ((the-file)[i]=" ") {
out=[out,out1];
var out1 = "";
} else {
out1=out1+(the-file)[i]
}
}
and (the-file) is the test input or the file you are using. out is the array out that you want to do stuff with and you may have to mess with it because it will probability not work
Related
I want paragraphs to be up to 3 sentences only.
For that, my strategy is to loop on all paragraphs and find the 3rd sentence ending (see note). And then, to add a "\r" char after it.
This is the code I have:
for (var i = 1; i < paragraphs.length; i++) {
...
sentEnds = paragraphs[i].getText().match(/[a-zA-Z0-9_\u0590-\u05fe][.?!](\s|$)|[.?!][.?!](\s|$)/g);
//this array is used to count sentences in Hebrew/English/digits that end with 1 or more of either ".","?" or "!"
...
if ((sentEnds != null) && (sentEnds.length > 3)) {
lineBreakAnchor = paragraphs[i].getText().match(/.{10}[.?!](\s)/g);
paragraphs[i].replaceText(lineBreakAnchor[2],lineBreakAnchor[2] + "\r");
}
}
This works fine for round 1. But if I run the code again- the text after the inserted "\r" char is not recognized as a new paragraph. Hence, more "\r" (new lines) will be inserted each time the script is running.
How can I make the script "understand" that "\r" means new, separate paragraph?
OR
Is there another character/approach that will do the trick?
Thank you.
Note: I use the last 10 characters of the sentence assuming the match will be unique enough to make only 1 replacement.
Without modifying your own regex expression you can achieve this.
Try this approach to split the paragraphs:
Grab the whole content of the document and create an array of sentences.
Insert paragraphs with up to 3 sentences after original paragraphs.
Remove original paragraphs from hell.
function sentenceMe() {
var doc = DocumentApp.getActiveDocument();
var paragraphs = doc.getBody().getParagraphs();
var sentences = [];
// Split paragraphs into sentences
for (var i = 0; i < paragraphs.length; i++) {
var parText = paragraphs[i].getText();
//Count sentences in Hebrew/English/digits that end with 1 or more of either ".","?" or "!"
var sentEnds = parText.match(/[a-zA-Z0-9_\u0590-\u05fe][.?!](\s|$)|[.?!][.?!](\s|$)/g);
if (sentEnds){
for (var j=0; j< sentEnds.length; j++){
var initIdx = 0;
var sentence = parText.substring(initIdx,parText.indexOf(sentEnds[j])+3);
var parInitIdx = initIdx;
initIdx = parText.indexOf(sentEnds[j])+3;
parText = parText.substring(initIdx - parInitIdx);
sentences.push(sentence);
}
}
// console.log(sentences);
}
inThrees(doc, paragraphs, sentences)
}
function inThrees(doc, paragraphs, sentences) {
// define offset
var offset = paragraphs.length;
// Create paragraphs with up to 3 sentences
var k=0;
do {
var parText = sentences.splice(0,3).join(' ');
doc.getBody().insertParagraph(k + offset , parText.concat('\n'));
k++
}
while (sentences.length > 0)
// Remove paragraphs from hell
for (var i = 0; i < offset; i++){
doc.getBody().removeChild(paragraphs[i]);
}
}
In case you are wondering about the custom menu, here is it:
function onOpen() {
var ui = DocumentApp.getUi();
ui.createMenu('Custom Menu')
.addItem("3's the magic number", 'sentenceMe')
.addToUi();
}
References:
DocumentApp.Body.insertParagraph
Actually the detection of sentences is not an easy task.
A sentence does not always end with a dot, a question mark or an exclamation mark. If the sentence ends with a quote then punctuation rules in some countries force you to put the end of the sentence mark inside the quote:
John asked: "Who's there?"
Not every dot means an end of a sentence, usually the dot after an uppercase letter does not end the sentence, because it occurs after an initial. The sentence does not end after J. here:
The latest Star Wars movie has been directed by J.J. Abrams.
However, sometimes the sentence does end after a capital letter followed by a dot:
This project has been sponsored by NASA.
And abbreviations can make it very hard:
For more information check the article in Phys. Rev. Letters 66, 2697, 2013.
Having in mind these difficulties let's still try to get some expression which will work in "usual" cases.
Make a global match and substitution. Match
((?:[^.?!]+[.?!] +){3})
and substitute it with
\1\r
Demo
This looks for 3 sentences (a sentence is a sequence of not-dot, not-?, not-! characters followed by a dot, a ? or a ! and some spaces) and puts a \r after them.
UPDATED 2020-03-04
Try this:
var regex = new RegExp('((?:[a-zA-Z0-9_\\u0590-\\u05fe\\s]+[.?!]+\\s+){3})', 'gi');
for (var i = 1; i < paragraphs.length; i++) {
paragraphs[i].replaceText(regex, '$1\\r');
}
I want to be able to extract a complete phone number from text, irrespective of how many spaces interrupt the number.
For example in the passage:
I think Emily was her name, and that her number was either 0421032614 or 0423 032 615 or 04321 98 564
I would like to extract:
0421032614
0423032615
0432198564
I can extract the first two using
(\d{4}[\s]?)(\d{3}[\s]?)+
But this is contingent on me knowing ahead of time how the ten numbers will be grouped (i.e. where the spaces will be). Is there any way to capture the ten numbers with a more flexible pattern?
You need to remove all white space then run a for loop and iterate through the groups:
public static void main (String [] args){
String reg = "(\\d{10})";
String word = " think Emily was her name, and that her number was either 0421032614 or 0423 032 615 or 04321 98 564";
word = word.replaceAll("\\s+",""); // replace all the whitespace with nothing
Pattern pat = Pattern.compile(reg);
Matcher mat = pat.matcher(word);
while (mat.find()) {
for (int i = 1; i <= mat.groupCount(); i++) {
System.out.println(mat.group(i));
}
}
}
output is
0421032614
0423032615
0432198564
Sorry but I am very new to Coldfusion and I need some help please.
I have a string that contains a recipe method. "Heat your oven to 200c and then blah blah until internal temperature measures 60c"
I need to replace the numeric values in the string with a dynamically calculated value and then it will look like this: "Heat your oven to 200c (392f) and then blah blah until internal temperature measures 60c (140f)".
These numeric values can appear anywhere and multiple times in the string.
The calculation to convert from C to F is C * 9/5 + 32.
So I need to ReReplace all numbers in the string with a new value calculated dynamically.
I hope this is clear.
This is my method of doing it.
<cfscript>
sString = "Heat your oven to 200c and then cook till the temp internally is 60c";
aFind = ReMatchNoCase("\d+c",sString);
x = 0;
while(x < arrayLen(aFind)){
x++;
nCalc = RematchNoCase("\d+",aFind[x])[1];
nCalc = nCalc*9/5+32;
sString = ReReplaceNoCase(sString,aFind[x],'#aFind[x]# (#ncalc#F)');
}
writeOutput(sString);
</cfscript>
Adams linked UDF might be better, but I guess this code example, serves as a look into how you might accomplish it without a 3rd party.
Items I have:
A large list A of strings in column A (unsorted)
name1 pattern1 pattern4
name5 pattern2
name4 pattern4
name2 pattern3 pattern1
name4 pattern4
A large list B of different string patterns that I want to remove from string in column A (include punctuation and special characters)
pattern1
pattern2
pattern3
Once I compare each pattern in B with the string in A, it should output:
name1 pattern4
name5
name4 pattern4
name2
name4 pattern4
Now I have 2 difficulties. I have a very simple test code, assuming there is only 1 pattern in list, the program executed error free however nothing happens in my google spreadsheet, which I can't explain why
function removeS(){
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A1:A");
var data = range.getValues();
for(i in data){
data[i].toString().replace(pattern,"");
}
}
Also secondly are there anyways I can accomplish my task without doing nested loop? (One loop through everything in column A and another loop for list of patterns) It seems so inefficient as I am dealing with large data. In Excel macro you can do sth like:
With ActiveSheet.UsedRange
.Replace pattern1, ""
.Replace pattern2, ""
and takes care of the need of using nested loops, although it takes manual work to add the patterns.
Here is an option. Although I'm not sure a more eloquent way than nested loops, without converting the returned spreadsheet values from a 2d to a 1d array.
I set a constant for the last row of the patterns column, assuming it was the short of the two columns (see comments in code for rational).
function cleanMe(){
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A1:A" + sheet.getLastRow());
var data = range.getValues();
// get the array of patterns (all ranges returned as 2d array)
// because .getLastRow() or .getDataRange returns the last row in the spreadsheet with data
// not the last row of the range with data
// hardcoded the last row in column be so as not to
// have to use conditions to check if values exist in range
var patternLastRow = 3;
var patterns = sheet.getRange("B1:B" + patternLastRow).getValues();
// 2d array to replace data in row A using range.setValues(newRange)
var newRange = [];
for(var i = 0; i < data.length; i++){
// use encodeURIComponent to contend with special charactes that would need escaping
var newValue = encodeURIComponent(data[i][0].toString());
for(var p = 0; p < patterns.length; p++){
var pattern = encodeURIComponent(patterns[p][0]);
var index = newValue.indexOf(pattern);
if(index >=0){
newValue = newValue.replace(pattern,'');
}
}
newRange.push([decodeURIComponent(newValue)]);
}
range.setValues(newRange);
}
I have a file that contains rows and columns of information like:
104857 Big Screen TV 567.95
573823 Blender 45.25
I need to parse this information into three separate items, a string containing the identification number on the left, a string containing the item name, and a double variable containing the price. The information is always found in the same columns, i.e. in the same order.
I am having trouble accomplishing this. Even when not reading from the file and just using a sample string, my attempt just outputs a jumbled mess:
string input = "104857 Big Screen TV 567.95";
string tempone = "";
string temptwo = input.substr(0,1);
tempone += temptwo;
for(int i=1 ; temptwo != " " && i < input.length() ; i++)
{
temptwo = input.substr(j,j);
tempone += temp2;
}
cout << tempone;
I've tried tweaking the above code for quite some time, but no luck, and I can't think of any other way to do it at the moment.
You can find the first space and the last space using std::find_first_of and std::find_last_of . You can use this to better split the string into 3 - first space comes after the first variable and the last space comes before the third variable, everything in between is the second variable.
How about following pseudocode:
string input = "104857 Big Screen TV 567.95";
string[] parsed_output = input.split(" "); // split input string with 'space' as delimiter
// parsed_output[0] = 104857
// parsed_output[1] = Big
// parsed_output[2] = Screen
// parsed_output[3] = TV
// parsed_output[4] = 567.95
int id = stringToInt(parsed_output[0]);
string product = concat(parsed_output[1], parsed_output[2], ... ,parsed_output[length-2]);
double price = stringToDouble(parsed_output[length-1]);
I hope, that's clear.
Well try breaking down the files components:
you know a number always comes first, and we also know a number has no white spaces.
The string following the number CAN have whitespaces, but won't contain any numbers(i would assume)
After this title, you're going to have more numbers(with no whitespaces)
from these components, you can deduce:
grabbing the first number is as simple as reading in using the filestream <<.
getting the string requires you to check until you reach a number, grabbing one character at a time and inserting that into a string. the last number is just like the first, using the filestream <<
This seems like homework so i'll let you put the rest together.
I would try a regular expression, something along these lines:
^([0-9]+)\s+(.+)\s+([0-9]+\.[0-9]+)$
I am not very good at regex syntax, but ([0-9]+) corresponds to a sequence of digits (this is the id), ([0-9]+\.[0-9]+) is the floating point number (price) and (.+) is the string that is separated from the two number by sequences of "space" characters: \s+.
The next step would be to check if you need this to work with prices like ".50" or "10".