Is there a way to simply replace string elements containing escape characters - ruby

From a file i import lines. In this line an (escaped) string is part of the line:
DP,0,"021",257
DP,1,"022",257
DP,2,"023",513
DP,3,"024",513
DP,4,"025",1025
DP,5,"026",1025
DP,6,"081",257
DP,7,"082",257
DP,8,"083",513
DP,9,"084",513
DP,10,"085",1025
DP,11,"086",1025
DP,12,"087",1025
DP,13,"091",257
DP,14,"092",513
DP,15,"093",1025
IS,0,"FIX",0
IS,1,"KARIN02",0
IS,2,"KARUIT02",0
IS,3,"KARIN02HOV",0
IS,4,"KARUIT02HOV",0
IS,5,"KARIN08",0
IS,6,"KARUIT08",0
IS,7,"KARIN08HOV",0
IS,8,"KARUIT08HOV",0
IS,9,"KARIN09",0
IS,10,"KARUIT09",0
IS,11,"KARIN09HOV",0
IS,12,"KARUIT09HOV",0
IS,13,"KARIN10",0
IS,14,"KARUIT10",0
IS,15,"KARIN10HOV",0
I get the following Objects (if DP) :
index - parts1 (int)
name - parts2 (string)
ref - parts3 (int)
I tried using REGEX to replace the excape-sequence from the lines but to no effect
#name_to_ID = {}
kruising = 2007
File.open(cfgFile).each{|line|
parts = line.split(",")
if parts[0]=="DP"
index = parts[1].to_i
hex = index.to_s(16).upcase.rjust(2, '0')
cname = parts[2].to_s
tname = cname.gsub('\\"','')
p "cname= #{cname} (#{cname.length})"
p "tname= #{tname} (#{tname.length})"
p cname == tname
#name_to_ID[tname] = kruising.to_s + "-" + hex.to_s
end
}
teststring = "021"
p #name_to_ID[teststring]
> "021" (5)
> "021" (5)
> true
> nil
The problem came to light when calling from another string reference (length3)
hash[key] isnt equal as string "021" ( length 5) is not string 021 ( length 3)
any method that actually replaces the chars i need?
EDIT: I used
cname.each_char{|c|
p c
}
> "\""
> "0"
> "2"
> "1"
> "\""
EDIT: requested outcome update:
# Current output:
#name_to_ID["021"] = 2007-00 "021".length = 5
#name_to_ID["022"] = 2007-01 "022".length = 5
#name_to_ID["081"] = 2007-06 "081".length = 5
#name_to_ID["082"] = 2007-07 "082".length = 5
#name_to_ID["091"] = 2007-0D "091".length = 5
#name_to_ID["101"] = 2007-10 "101".length = 5
# -------------
# Expected output:
#name_to_ID["021"] = 2007-00 "021".length = 3
#name_to_ID["022"] = 2007-01 "022".length = 3
#name_to_ID["081"] = 2007-06 "081".length = 3
#name_to_ID["082"] = 2007-07 "082".length = 3
#name_to_ID["091"] = 2007-0D "091".length = 3
#name_to_ID["101"] = 2007-10 "101".length = 3

Your problem is you don't know the correct character in your string. It might not be the same character when printing it.
Try parts[2].to_s.bytes to check exactly what is the character code of that unexpected character. For example:
> "͸asd".bytes
=> [205, 184, 97, 115, 100]
Alternatively, you can delete the first and the last characters, if you are sure that every part of the string has the same format:
cname = parts[2].to_s[1..-2]
Or you can remove all special characters in the string if you know that the string will not contain any special character
cname = parts[2].to_s.gsub(/[^0-9A-Za-z]/, '')

Related

require solution for string replacement

I have a code where I have to replace a string with another string.
My file contains
secondaryPort = 7504
The code below
filtered_data =
filtered_data.gsub(
/secondaryPort=\d+/,
'secondaryPort=' + node['server']['secondaryPort']
)
should replace my file with
secondaryPort = 7555
but it fails to do so.
Make sure you account for the spaces around the equals sign in your string:
filtered_data = 'secondaryPort = 7504'
=> 'secondaryPort = 7504'
# with literal spaces
filtered_data.gsub(/secondaryPort = \d+/, 'secondaryPort = 7555')
=> 'secondaryPort = 7555'
# with regex character class for literal space
filtered_data.gsub(/secondaryPort\s{1}=\s{1}\d+/, 'secondaryPort = 7555')
=> 'secondaryPort = 7555'

How to read by the number at each iteration of the loop in Ruby?

How to read by the number at each iteration of the loop? Dynamic work is important, (not once to read the entire line and convert to an array), at each iteration, take one number from the file string and work with it. How to do it right?
input.txt :
5
1 7 5 2 3
Work with 2nd line of the file.
fin = File.open("input.txt", "r")
fout = File.open("output.txt", "w")
n = fin.readline.to_i
heap_min = Heap.new(:min)
heap_max = Heap.new(:max)
for i in 1..n
a = fin.read.to_i #code here <--
heap_max.push(a)
if heap_max.size > heap_min.size
tmp = heap_max.top
heap_max.pop
heap_min.push(tmp)
end
if heap_min.size > heap_max.size
tmp = heap_min.top
heap_min.pop
heap_max.push(tmp)
end
if heap_max.size == heap_min.size
heap_max.top > heap_min.top ? median = heap_min.top : median = heap_max.top
else
median = heap_max.top
end
fout.print(median, " ")
end
If you're 100% sure that your file separate numbers by space you can try this :
a = fin.gets(' ', -1).to_i
Read the 2nd line of a file:
line2 = File.readlines('input.txt')[1]
Convert it to an array of integers:
array = line2.split(' ').map(&:to_i).compact

Sphinx:Search:How to index and find words with separator "-"

Can't index and find words such as 'N-7' and etc. by sphinx.
Directives "charset_table", symbols was added - but not working.
What else to do?
Sphinx 2.2.10 config
index site
{
charset_table = 0..9, A..Z->a..z, _, -, a..z, \
U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451, U+2D
type = rt
path = /var/lib/sphinx/site
ondisk_attrs=1
morphology = lemmatize_ru_all, lemmatize_en_all, lemmatize_de_all, stem_enru
prefix_fields = title
infix_fields=
min_prefix_len = 2
expand_keywords = 1
min_word_len = 3
stopwords = /etc/sphinx/stopwords.txt
}
Vladimir.

Better way to return values from split

I need to parse a field from a CSV column which is a string:
TXDAT - SnpRespData_SC or SnpRespData_SC_PD (7)
I need to extract:
type_0 = SnpRespData
resp_0 = SC
pd_0 = 0
type_1 = SnpRespData
resp_1 = SC
pd_1 = 1
from this string. I want to pass the whole string to a function and be able to return these six values.
The string could be any of the following:
a) TXDAT - SnpRespData_SC_PD
b) TXRSP - SnpResp_SC
c) TXDAT - SnpRespData_SC or SnpRespData_SC_PD (7)
d) TXRSP - SnpResp_UC or TXDAT - SnpRespData_UC_PD (7)
So I created a function which receives this string and returns the following:
def map_rxsnp_transaction(rxsnp_transaction)
tx_dat = []
tx_rsp = []
case rxsnp_transaction
when (/SnpRespData.*SnpRespData/)
tx_dat = rxsnp_transaction.split(/or/)
(tx_dat_0, dat_0_resp, dat_0_pd) = tx_dat[0].split(/_/)
(tx_dat_1, dat_1_resp, dat_1_pd) = tx_dat[1].split(/_/)
return [tx_dat_0, dat_0_resp, dat_0_pd, tx_dat_1, dat_1_resp, dat_1_pd]
when (/SnpResp.*SnpRespData/)
(tx_rsp, tx_dat) = rxsnp_transaction.split(/or/)
(tx_rsp, rsp_resp, rsp_pd) = tx_rsp.split(/_/)
(tx_dat, dat_resp, dat_pd) = tx_dat.split(/_/)
return [tx_rsp, rsp_resp, rsp_pd, tx_dat, dat_resp, dat_pd]
when (/SnpRespData_{1}/)
return rxsnp_transaction.split(//)
when (/SnpResp{1}/)
return rxsnp_transaction.split(/_/)
end
end
Function call:
(tx_rsp[0],tx_rsp[1],tx_rsp[2],tx_rsp[3],tx_rsp[4],tx_rsp[5]) = map_rxsnp_transaction table_col[5]
Just wondering if I can optimize this code better...don't like the way it
I assume that you are looking for a specific string, namely, "SnpRespData". If so, you could do this:
str = "TXDAT - SnpRespData_SC or SnpRespData_SC_PD (7)"
f, l = str.scan(/SnpRespData\w+/).sort
#=> ["SnpRespData_SC", "SnpRespData_SC_PD"]
type_0, resp_0, pd_0 = f.split('_') << 0
#=> ["SnpRespData", "SC", 0]
type_1, resp_1, pd_1 = f.split('_').first(2) << 1
#=> ["SnpRespData", "SC", 1]
type_0 #=> "SnpRespData"
resp_0 #=> "SC"
pd_0 #=> 0
type_1 #=> "SnpRespData"
resp_1 #=> "SC"
pd_1 #=> 1

Conditionally modifying multiple strings with For

So I have 13 binary values, which I call b_1... b_13, and based off these values I'd like to either set something I call indic_j to a previously defined string called inf_j, or nothing at all. Is it possible to do this without using 13 "If..." statements? What I have tried is below:
inf_1 = "aaaaa"
inf_2 = "bbbbb"
... and so on defining 13 infs, where aaaaa, bbbbb etc are names of columns in a table that I want to select.
FOR j = 1 to 13
IF b_j = 1 THEN "indic_"+j = inf_j + ",";
ELSE "indic_"+j = ""
ENDIF
ENDFOR
Also, before this I haven't introduced anything called indic_1, indic_2, etc. Is this needed?
My end goal is to transfer selected columns over to Excel. I've no problems doing this with predetermined columns, but I'm not sure how to allow for selected columns only.
I've tried using 13 IF statements, but I'm getting operator/operand type mismatch errors. My code currently is
IIF(b_1 = 1, indic_1 = inf_1 + ",",indic_1 = "")
IIF(b_2 = 1, indic_1 = inf_2 + ",",indic_1 = "")
IIF(b_3 = 1, indic_1 = inf_3 + ",",indic_1 = "")
and so on for 13 times, and then
SELECTIONRANG = indic_1 + indic_2 + indic_3 + indic_4 + indic_5 + indic_6 +indic_7 + indic_8 + indic_9 + indic_10 + indic_11 + indic_12 + indic_13
SELECTIONRANGE = LEFT(SELECTIONRANG,LEN(Selectionrang)-1)
You could create te variable name as a string and use it with &
As:
ind = 13
Var = "inf_" + ind
&Var ** inf_13

Resources