This is decoded string from bytes, they are always different. Am not using it in the code, its just for shown what is all about.
"Background:Sunfire Topo;Base:Eagle;Accessory3:None;Patch:Oreo;Jacket:Pink Bonez;Eyes:BloodShot;Beak:Drool;Accessory2:Nose Ring;Accessory1:None;Item:Knife;tags:Dope Eagles,ELEMENT-HYDRO,ATTACK-10,DEFENSE-5,HIGHNESS-4,SWAG-1;metadata:QmU7JcFDoGcUvNkDgsPz9cy13md4xHdNyD6itwmgVLuo7x/860.json"
This is array of bytes from above string which i get as input.
[66, 97, 99, 107, 103, 114, 111, 117, 110, 100, 58, 83, 117, 110, 102, 105, 114, 101, 32, 84, 111, 112, 111, 59, 66, 97, 115, 101, 58, 69, 97, 103, 108, 101, 59, 65, 99, 99, 101, 115, 115, 111, 114, 121, 51, 58, 78, 111, 110, 101, 59, 80, 97, 116, 99, 104, 58, 79, 114, 101, 111, 59, 74, 97, 99, 107, 101, 116, 58, 80, 105, 110, 107, 32, 66, 111, 110, 101, 122, 59, 69, 121, 101, 115, 58, 66, 108, 111, 111, 100, 83, 104, 111, 116, 59, 66, 101, 97, 107, 58, 68, 114, 111, 111, 108, 59, 65, 99, 99, 101, 115, 115, 111, 114, 121, 50, 58, 78, 111, 115, 101, 32, 82, 105, 110, 103, 59, 65, 99, 99, 101, 115, 115, 111, 114, 121, 49, 58, 78, 111, 110, 101, 59, 73, 116, 101, 109, 58, 75, 110, 105, 102, 101, 59, 116, 97, 103, 115, 58, 68, 111, 112, 101, 32, 69, 97, 103, 108, 101, 115, 44, 69, 76, 69, 77, 69, 78, 84, 45, 72, 89, 68, 82, 79, 44, 65, 84, 84, 65, 67, 75, 45, 49, 48, 44, 68, 69, 70, 69, 78, 83, 69, 45, 53, 44, 72, 73, 71, 72, 78, 69, 83, 83, 45, 52, 44, 83, 87, 65, 71, 45, 49, 59, 109, 101, 116, 97, 100, 97, 116, 97, 58, 81, 109, 85, 55, 74, 99, 70, 68, 111, 71, 99, 85, 118, 78, 107, 68, 103, 115, 80, 122, 57, 99, 121, 49, 51, 109, 100, 52, 120, 72, 100, 78, 121, 68, 54, 105, 116, 119, 109, 103, 86, 76, 117, 111, 55, 120, 47, 56, 54, 48, 46, 106, 115, 111, 110]
What i need is get the values from ELEMENT, ATTACK,DEFENSE,HIGHNESS,SWAG. While every byte in the array is changing. but some bytes are always same. I was thinking if there is any way how to extract it without using any Strings... Thanks for any ideas
so the output would look like this:
let element = [72, 89, 68, 82, 79];
let attack = [49, 48];
let defense = [53];
let highness = [52];
let swag = [49];
CodePudding user response:
You can do all this without allocating any extra space using rusts iterators, using split
and related functions
At the top level, your data is of the form (key:value;)*
This suggests first splitting on ;
Then splitting each of these pieces into key and value using :
In your case, all the information is when the key
is "tags"
.
Then within the tags section, you again have (mostly) key-value pairs of the form (key-value,)*
so we need to split on ,
then break into key-value pairs using -
.
An example that does this but only prints all the tag key-value pairs is:
fn split_kv(v: &[u8], c: u8) -> Option<(&[u8], &[u8])> {
let n = v.iter().position(|&b| b == c)?;
let w = v.split_at(n);
Some((w.0, &(w.1)[1..]))
}
fn main() {
let s: &str = "Background:Sunfire Topo;Base:Eagle;Accessory3:None;Patch:Oreo;Jacket:Pink Bonez;Eyes:BloodShot;Beak:Drool;Accessory2:Nose Ring;Accessory1:None;Item:Knife;tags:Dope Eagles,ELEMENT-HYDRO,ATTACK-10,DEFENSE-5,HIGHNESS-4,SWAG-1;metadata:QmU7JcFDoGcUvNkDgsPz9cy13md4xHdNyD6itwmgVLuo7x/860.json";
let ss: &[u8] = s.as_bytes();
let tags = ss
.split(|&b| b == b';') // Break up at ';'
.filter_map(|s| split_kv(s, b':')) // Split each piece into key-value pairs using ':'
.filter_map(|(k, v)| { // Only keep the tags entry.
if k == "tags".as_bytes() {
Some(v)
} else {
None
}
})
.next() // And just take the first of those.
.unwrap();
// Split the tags by ','
for t in tags.split(|&b| b == b',') {
// Then try to convert each to a key-value using '-' as seperator.
if let Some((k, v)) = split_kv(t, b'-') {
println!(
"k={:?} v={:?}",
std::str::from_utf8(k).unwrap(),
std::str::from_utf8(v).unwrap()
);
} else {
println!("t={:?}", std::str::from_utf8(t).unwrap());
}
}
}
You can run this here