Flutter: how to split a list of string that contain html tags using regex? - flutter

I try to split the list of sentences which have html tags as below:
The sky is clear and the stars are twinkling.
They were excited to see their first sloth.
Douglas figured the best way to succeed was to do the opposite of what he'd been doing all his life.
The result I want is as below:
[The, sky, is clear and the, stars, are twinkling.]
[They were, excited, to see their first sloth.]
[Douglas figured the best way to, succeed, was to do the, opposite, of what he'd been doing all his life.]
How am I able to do it with RegExp in order to get above result?

For example this is your string:
String str =
"The sky is clear and the stars are twinkling. They were excited to see their first sloth. Douglas figured the best way to succeed was to do the opposite of what he'd been doing all his life.";
you clan split it like this:
final reg = RegExp("<[^>]*>");
var result = str.split(reg);
print('result = $result'); // [The , sky, is clear and the , stars, are twinkling. They were , excited, to see their first sloth. Douglas figured the best way to , succeed, was to do the , opposite, of what he'd been doing all his life.]
if you want it with tag, try this(tanks to #JovenDev):
final reg = RegExp("(?=<a)|(?<=/a>)");
var result = str.split(reg);
print('result = $result'); // [The , sky, is clear and the , stars, are twinkling. They were , excited, to see their first sloth. Douglas figured the best way to , succeed, was to do the , opposite, of what he'd been doing all his life.]

Related

How do i exclude some elements of a list from further calculations

So I have a list of stars and their respective distances. My assignment is to find which stars are in a certain distance (+- 10parsec). I want to exclude some of them from further calculations in the program. The thing is I don't want to remove them completely so remove, pop etc isn't helping me. I still want those stars on the list to be present in my output csv. I just want a line saying something like those stars which don't support the if statement, don't use them in this calculation. So i guess the output would be blank for those.
I suppose it is an if or for statement, to mark those bad stars as False and then down the line use calculation that excludes those faulty stars.
I'm a physics student and this is my first python program ever! Please be cool about my ignorance...
Edit: forgive me if i include useless stuff i don't really know what's important. I also use uncertainties library if its of any use
column_names = ['id','pi','s_pi','v_r' ,'s_v', 'dis', 'X',
'ra_h', 'ra_m', 'ra_s','dec_d', 'dec_m',
'dec_s', 'ma', 's_ma', 'md', 's_md']
data = pd.read_csv("hyades_data.dat", skiprows=2, sep='\s+',
names=column_names)
calculations with all
v_r = unumpy.uarray(data['v_r'], data['s_v'])
ma = unumpy.uarray(data['ma'], data['s_ma'])
md = unumpy.uarray(data['md'], data['s_md'])
mi = unumpy.sqrt(ma**2+md**2)
r_m = v_r*unumpy.tan(th)/(4.74*mi/1000)
diff = np.abs(r_pc - r_m)
'''
if np.abs(dist-46.43) <=10:
r_m=True
else r_m=False
at this point i want to make the distiction
'''
mean_diff = diff.mean()
print("Mean : ")
print(mean_diff)
print(a_ref,d_ref)
df_va=pd.DataFrame(v_r)
df_mi = pd.DataFrame(mi)
df_rm = pd.DataFrame(r_m)
df_rpc = pd.DataFrame(r_pc)
df_diff = pd.DataFrame(diff)
#df_mean_diff = pd.DataFrame(mean_diff)
ve = v_r*np.tan(th)
output = pd.concat([data['id'], ra, dec, th_d, df_mi, df_rm, df_rpc,
df_diff,df_va], axis=1)
output.columns = ['id','ra', 'dec', 'th_d','mi', 'r_m', 'r_pc',
'dist_diff','va']
output.to_csv('results.csv', index=False)

"Appending" to an ArraySlice?

Say ...
you have about 20 Thing
very often, you do a complex calculation running through a loop of say 1000 items. The end result is a varying number around 20 each time
you don't know how many there will be until you run through the whole loop
you then want to quickly (and of course elegantly!) access the result set in many places
for performance reasons you don't want to just make a new array each time. note that unfortunately there's a differing amount so you can't just reuse the same array trivially.
What about ...
var thingsBacking = [Thing](repeating: Thing(), count: 100) // hard limit!
var things: ArraySlice<Thing> = []
func fatCalculation() {
var pin: Int = 0
// happily, no need to clean-out thingsBacking
for c in .. some huge loop {
... only some of the items (roughly 20 say) become the result
x = .. one of the result items
thingsBacking[pin] = Thing(... x, y, z )
pin += 1
}
// and then, magic of slices ...
things = thingsBacking[0..<pin]
(Then, you can do this anywhere... for t in things { .. } )
What I am wondering, is there a way you can call to an ArraySlice<Thing> to do that in one step - to "append to" an ArraySlice and avoid having to bother setting the length at the end?
So, something like this ..
things = ... set it to zero length
things.quasiAppend(x)
things.quasiAppend(x2)
things.quasiAppend(x3)
With no further effort, things now has a length of three and indeed the three items are already in the backing array.
I'm particularly interested in performance here (unusually!)
Another approach,
var thingsBacking = [Thing?](repeating: Thing(), count: 100) // hard limit!
and just set the first one after your data to nil as an end-marker. Again, you don't have to waste time zeroing. But the end marker is a nuisance.
Is there a more better way to solve this particular type of array-performance problem?
Based on MartinR's comments, it would seem that for the problem
the data points are incoming and
you don't know how many there will be until the last one (always less than a limit) and
you're having to redo the whole thing at high Hz
It would seem to be best to just:
(1) set up the array
var ra = [Thing](repeating: Thing(), count: 100) // hard limit!
(2) at the start of each run,
.removeAll(keepingCapacity: true)
(3) just go ahead and .append each one.
(4) you don't have to especially mark the end or set a length once finished.
It seems it will indeed then use the same array backing. And it of course "increases the length" as it were each time you append - and you can iterate happily at any time.
Slices - get lost!

Display certain number of letters

I have a word that is being displayed into a label. Could I program it, where it will only show the last 2 characters of the word, or the the first 3 only? How can I do this?
Swift's string APIs can be a little confusing. You get access to the characters of a string via its characters property, on which you can then use prefix() or suffix() to get the substring you want. That subset of characters needs to be converted back to a String:
let str = "Hello, world!"
// first three characters:
let prefixSubstring = String(str.characters.prefix(3))
// last two characters:
let suffixSubstring = String(str.characters.suffix(2))
I agree it is definitely confusing working with String indexing in Swift and they have changed a little bit from Swift 1 to 2 making googling a bit of a challenge but it can actually be quite simple once you get a hang of the methods. You basically need to make it into a two-step process:
1) Find the index you need
2) Advance from there
For example:
let sampleString = "HelloWorld"
let lastThreeindex = sampleString.endIndex.advancedBy(-3)
sampleString.substringFromIndex(lastThreeindex) //prints rld
let secondIndex = sampleString.startIndex.advancedBy(2)
sampleString.substringToIndex(secondIndex) //prints He

Logical indexing of fields within a structure

I have a structure like so:
Basis.FieldsBasisType.fieldsBasisComponents
There are ~13 components to each basis, including 6 asset class IDs.
So, for example
fieldnames(Basis.SalaryIncrease) =
'Constant'
'AWeight'
'AAssetClassID'
'ATimeLag'
'BWeight'
'BAssetClassID'
'BTimeLag'
'CWeight'
'CAssetClassID'
'CTimeLag'
'DWeight'
'DAssetClassID'
'DTimeLag'
'EWeight'
'EAssetClassID'
'ETimeLag'
'FWeight'
'FAssetClassID'
'FTimeLag'
'cap'
'floor'
Now what I want to do is select all unique asset classes used in any basis. I am really struggling to make this neat though, currently I am using:
basisNames = fieldnames(Basis);
requiredSeries=[];
for i = 1:size(fieldnames(Basis),1)
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).AAssetClassID)];
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).BAssetClassID)];
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).CAssetClassID)];
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).DAssetClassID)];
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).EAssetClassID)];
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).FAssetClassID)];
end
requiredSeries = unique(requiredSeries)
Which is really ugly in my opinion. I want to do some kind of string compare to find 'AssetClassID' within the fields, so something like:
field = fieldnames(Basis.(basisNames{1}));
strfind(field,'AssetClassID');
And then use that cell array to logically index 'field' and just grab the data from 'AssetClassID' fields. But I am stuck on making that work.
~cellfun('isempty',strfind(field,'AssetClassID'))
gets me the logical index, how do I apply that to fields and then use it to get values.
Any ideas would be appreciated, I feel there should be a neat way of doing it and I am missing something. Hardcoding those fieldnames seems short sighted as a solution.
#
Edit: I hate myself.
Sorry folks, I came up with a working variant like moments after posting this, apologies for wasting anyones time!
basisNames = fieldnames(Basis);
for i = 1:size(fieldnames(Basis),1)
field = fieldnames(Basis.(basisNames{i}));
field = cell2mat(field(~cellfun('isempty',strfind(field,'AssetClassID'))));
for j = 1:size(field,1)
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).(field(1,:)))];
end
requiredSeries = unique(requiredSeries)
end
I was missing a necessary cell2mat earlier which caused the inability to get it to bloody work. Anyway, I'd always like to hear improvements to that but otherwise you can shut this down.
Sorry folks, I came up with a working variant 30 mins or after posting this, popping it down as an answer as per Michelle's suggestion.
basisNames = fieldnames(Basis);
for i = 1:size(fieldnames(Basis),1)
field = fieldnames(Basis.(basisNames{i}));
field = cell2mat(field(~cellfun('isempty',strfind(field,'AssetClassID'))));
for j = 1:size(field,1)
requiredSeries = [requiredSeries;unique(Basis.(basisNames{i}).(a(1,:)))];
end
requiredSeries = unique(requiredSeries)
end
I was missing a necessary cell2mat earlier which caused the inability to get it to bloody work. Anyway, I'd always like to hear improvements to that but otherwise you ignore this entirely :)

Substring a text since the target founded

I have a search on my php page and it is ok.
With my search result, I highlighted the string target on my content.
$search_tag_text = #preg_replace("/($mysearch)/i", "<u style=\"color:red\">$1</u>", $row->txtContent);
Ok, but is it possible, after having found a string target on my content, to show 20 words before and 20 words after, instead listing all my content?
Any help will be appreciated.
I would try something like:
$matches = array();
preg_match("/($mysearch)/i", $search_tag_text, $matches, PREG_OFFSET_CAPTURE);
And then in the match you would have the offset of where the found string is, then you could do:
$search_tag_text = substr($subject, ($matches[0][1] - 30), 60);
For 30 characters before the match and 30 after. If i've understood correctly the last element in $mathces[i][x] is the offset where the match was found.