how do I split string by space and following specific number? My string looks like
PID55688.00976 1
PID66854.76557 2
PID88774.23455 3
PID66843.99754 1
PID66800.00764 3
I want to split string by space and number 3
Code
str.split(/\s3/) does not split anything.
This produces the expected output that OP has describe in the comments on #spickermann's answer:
string = <<-STRING
PID55688.00976 1
PID66854.76557 2
PID88774.23455 3
PID66843.99754 1
PID66800.00764 3
STRING
string.split(/ 3\n/).map{|substring| (substring+" 3").split(/\n/)}
but there's some typos in OP's expected answer, as there's no commas or quotes in the arrays. So I might have misinterpreted.
I would do something like this:
string = <<-STRING
PID55688.00976 1
PID66854.76557 2
PID88774.23455 3
PID66843.99754 1
PID66800.00764 3
STRING
string.scan(/(\w+\.\w+ \w+)\n/).flatten
#=> [["PID55688.00976 1"], ["PID66854.76557 2"], ["PID88774.23455 3"], ["PID66843.99754 1"], ["PID66800.00764 3"]]
Assuming
[["PID55688.00976 1", "PID66854.76557 2", "PID88774.23455 3"],
["PID66843.99754 1", "PID66800.00764 3"]]
is the desired return value, one could write:
string.split(/\r?\n/).slice_after { |s| s.end_with?(' 3') }.to_a
See Enumerable#slice_after and String#end_with?.
Related
I am making a program which takes user input and handles that input based on the user's choice of options. Say I input a string like "hello 4 is a number, and 5 is as well". How can I take the numbers from the string and put them in variables? (In my example I am looking to use the 4 and 5.)
So, i write some code to solve your problem. First and easyest case: you pass the sentence as a list, like this [hello,4,is,5,and]. In this case, you need to check if an element of the list is a number with number/1:
parseSentence([],[]).
parseSentence([H|T],L):-
\+(number(H)),
parseSentence(T,L).
parseSentence([H|T],[H|T1]):-
number(H),
parseSentence(T,T1).
?- parseSentence([hello,4,is,5,and],L).
L = [4, 5].
false
Second and most interesting case: you pass the sentence as a string, like this: "hello 4 is a number, and 5 is as well". Here the code (a bit redundant to make it more clear):
parseSentenceMod([],[]).
parseSentenceMod([H|T],[A|T1]):-
atom_number(H,A),
parseSentenceMod(T,T1).
parseSentenceMod([H|T],L):-
\+(atom_number(H,_)),
parseSentenceMod(T,L).
findAtom([],[]).
findAtom([H|T],[H1|T1]):-
atom_string(H1,H),
findAtom(T,T1).
parseString(S,P,A,N):-
split_string(S," ","",P),
findAtom(P,A),
parseSentenceMod(A,N).
?- parseString("hello 4 is a number, and 5 is as well",S,A,N).
A = [hello, '4', (is), a, 'number,', and, '5', (is), (as), well],
N = [4, 5],
S = ["hello", "4", "is", "a", "number,", "and", "5", "is", "as", "well"]
false
atom_number/2 checks if the atom is a number, atom_string/2 creates an atom given a string and split_string/4 splits the string in substrings separated by, in this case, a blank space. Hope it helps.
Given a list of small strings (1 to 3 words each), I would like to print them in 2 columns using ZPL for Zebra Printers. For example, if the list is ["A", "B", "C", "D", "E"], I would like my label to look like this:
A B
C D
E
However, if strings are a little bit longer, I would like to be able to truncate them so that columns don't overlap. For example, if the list is ["string 1", "string 2", "long string 3", "string 4", "string 5"], the label should look like this:
string 1 string 2
long str string 4
string 5
I see 2 possible approaches to this:
1) Using some ZPL command that I have not been able to find yet
2) Calculating the width of the strings in pixels. In this case I would need to know what is the font used by ZPL.
I'm using this command for text printing:
^A0,N,30,30
^FDtext^FS
It looks like ^TB is the solution:
^A0N,30,30
^TBN,250,29
^FDtext should go here^FS
I was wondering if it was possible to split a string into multiple partitions of various lengths. I would like to split this string for example:
string = "1 name lastname 234 washington city/NY"
into four sub-strings, where:
1st partition to have 1st 2 characters ("1 ")
2nd partition to
have subsequent 15 characters ("name lastname ")
3rd partition
to have subsequent 6 characters ("234 ")
4rd partition to have
subsequent 20 characters ("washington city/NY")
you do this simply by indexing:
string[0,2]
string[4,15]
stirng[20,6]
string[27,20]
Writing a Regexp isn't that hard. The free-spacing mode lets you write the pattern on multiple lines and supports comments. Here's an example with named captures groups:
string = "1 name lastname 234 washington city/NY"
pattern = /\A
(?<id>.{2}) # 2 charcters for the id
(?<name>.{20}) # 20 characters for the name
(?<zip>.{6}) # 6 characters for the zip code
(?<city>.+) # remaining characters for city and state
\Z/x
match = string.match(pattern)
#=> #<MatchData "1 name lastname 234 washington city/NY" id:"1 " name:"name lastname " zip:"234 " city:"washington city/NY">
match[:id] #=> "1 "
match[:name] #=> "name lastname "
match[:zip] #=> "234 "
match[:city] #=> "washington city/NY"
With Ruby, how can I get the diff between two strings, then use the identical parts as a base to split the rest?
For example, I have two strings (Not all strings will have this formatting):
String1 = "Computer: Person1, Title: King, Phone: 555-1212"
String2 = "Computer: PersonB, Title: Queen, Phone: 123-4567"
I would like to be able to compare (diff) the two strings so that I get the result:
["Computer: ",", Title:",", Phone:"]
then use this to reparse the original strings to get:
["Person1","King","555-1212"] and ["PersonB","Queen","123-4567"]
which I could label in db/storage with the former array.
Are there features to do this and how would I achieve these results?
The object of this is not need prior knowledge of formatting. This way just the data are analyzed for patterning and then divided as such. It may be comma delimited, new lines, spaced out, etc.
I am looking at gem "diffy" and "diff-lcs" to see if they might help split this up.
I think all you need is a hash, with hash you can do anything fancy.
>> String1 = "Computer: Person1, Title: King, Phone: 555-1212"
>> a = String1.gsub(/[^\s\:]/) { |w| "\"#{w}\"" }
>> a.insert(0, "{")
>> a.insert(-1, "}")
>> a1 = JSON.parse(a)
>> #=> {
"Computer" => "Person1",
"Title" => "King",
"Phone" => "555-1212"
}
Then you can request what you want in question, like
>> a1["Computer"]
>> #=> "Person1"
Add
And you can abstract it to a method further
def str_to_hash(str)
ouput = str.gsub(/[^\s\:]/) { |w| "\"#{w}\"" }
output.insert(0, "{").insert(-1, "}")
JSON.parse(out)
end
>> h2 = str_to_hash(String2)
>> h2["Computer"]
>> #=>"PersonB"
String1 = "Computer: Person1, Title: King, Phone: 555-1212"
String2 = "Computer: PersonB, Title: Queen, Phone: 123-4567"
keys = String1.split - (String1.split - String2.split)
values = String1.split - keys
You need to find a suitable way to split for your specific data. For instance, if values are allowed to contain spaces inside double quotes, you can to something like .split(/"?[^ ]*\ ?[^ ]*"?/), but there is no general solution for this, that will handle any type of data.
And then you need to clean up the resulting values.
Given those strings, I would rather split columns by ,, then use the part before : as name of column.
There is an longest common subsequence problem, which has something to do, but is not smart enough to handle semantics of data.
s1 = String1.split(' ')
s2 = String2.split(' ')
s1 - s2
=> ["Person1,", "King,", "555-1212"]
s2 - s1
=> ["PersonB,", "Queen,", "123-4567"]
I am having quite the difficulty using regex in ruby to split a string along several delimiters these delimiters are:
,
/
&
and
each of these delimiters can have any amount of white space on either side of the delimiter but each item can contain a valid space.
a great example that I've been testing against is the string 1, 2 /3 and 4 12
what I would like is something around the lines of "1, 2 /3 and 4 12".split(regex) =>["1", "2", "3", "4 12"]
The closest I've been able to get is /\s*,|\/|&|and \s*/ but this generates ["1", " 2 ", "3 ", "4 12"] instead of the desired results.
Realize this is very close and I could simply all trim on each item, but being so close and knowing it can be done is sort of driving me mad. Hopefully someone can help me keep the madness at bay.
/\s*,|\/|&|and \s*/
This parses as /(\s*,)|\/|&|(and \s*)/. I.e. the leading \s* only applies to the comma and the trailing \s* only applies to "and". You want:
/\s*(,|\/|&|and )\s*/
Or, to avoid capturing:
/\s*(?:,|\/|&|and )\s*/
Try .scan:
irb(main):030:0> "1, 2 /3 and 4 12".scan(/\d+(?:\s*\d+)*/)
=> ["1", "2", "3", "4 12"]
You can try:
(?:\s*)[,\/](?:\s*)|(?:\s*)and(?:\s*)
But as Nakilon suggested, you may have better luck with scan instead of split.