# Help parsing and extracting a num

**URL:** <https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883>\
**Category:** Ruby\
**Created:** [March 25, 2008, 3:39pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883 "2008-03-25T15:39:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [March 25, 2008, 3:39pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883/1 "2008-03-25T15:39:29Z")

</div>

Hi, I’m trying to extract a num from a string. This string is in fact  
some number of headers separated by \r\n or \n. for now I just need to  
extract the value of “Content-Length” (case insensitive) header.

For example:

irb\> headers = “Via: via1,via2,\r\n via3\r\nFrom:  
from\_user@domain\nContent-length: 22\r\nTo: to\_user@domain\n”

I do the following:

irb\> headers.scan(/content-length\s\*:\s\*([0-9]\*)/i).to\_s.to\_i  
=\> 22

In case the “Content-Length” header exist but has empty value I get 0  
with the above code (that’s what I need in fact).

Is there any way faster to do the same? any help?

Thanks a lot.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [March 25, 2008, 3:51pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883/2 "2008-03-25T15:51:24Z")

</div>

2008/3/25, Iñaki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Hi, I’m trying to extract a num from a string. This string is in fact  
> some number of headers separated by \r\n or \n. for now I just need to  
> extract the value of “Content-Length” (case insensitive) header.

Why don’t you use Net::Http? IIRC this gives you individual header  
fields already.

> In case the “Content-Length” header exist but has empty value I get 0  
> with the above code (that’s what I need in fact).
> 
> Is there any way faster to do the same? any help?

headers[/content-length:\s\*(\d+)/i, 1].to\_i

Cheers

robert

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [March 25, 2008, 4:03pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883/3 "2008-03-25T16:03:22Z")

</div>

2008/3/25, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 2008/3/25, IÃ±aki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Hi, I’m trying to extract a num from a string. This string is in fact  
> > some number of headers separated by \r\n or \n. for now I just need to  
> > extract the value of “Content-Length” (case insensitive) header.
> 
> Why don’t you use Net::Http? IIRC this gives you individual header  
> fields already.

Yes, but I’m doing a parser for SIP protocol (similar to HTTP but not  
the same).

> headers[/content-length:\s\*(\d+)/i, 1].to\_i

Great !

Thanks.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [March 25, 2008, 5:35pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883/4 "2008-03-25T17:35:13Z")

</div>

2008/3/25, IÃ±aki Baz C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> "Via: via1,via2,\r\n via3\r\nFrom: from\_user@domain\nContent-length:
> 
> \r\n1234: blabla\nTo: to\_user@domain\n"[/content-length\s\*:\s\*(\d+)/i,  
> 1].to\_i  
> =\> 1234
> 
> I’m trying to solve it by ading [^(\r|\n)] after (\d+) but I get  
> nothing. Please, could you help me with this?

I think I have now the solution. The problem is that \s matches also  
\n so what I do now is:

[/content-length\s\*:[\t]\*(\d+)/i, 1].to\_i

(I allow any space or tab before the expected numbers but no \r or \n).

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [March 25, 2008, 5:29pm UTC](https://www.ruby-forum.com/t/help-parsing-and-extracting-a-num/132883/5 "2008-03-25T17:29:40Z")

</div>

> 2008/3/25, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > headers[/content-length:\s\*(\d+)/i, 1].to\_i

There is a small issue here that I can’t solve. Imagine there is  
“Content-Length” header bt with empty value, and the next header has a  
numeric header name:

* * *

## Content-Length: 1234: blablabla

In that case the code above returns 1234 while it should return 0.

Demostration:

“Via: via1,via2,\r\n via3\r\nFrom: from\_user@domain\nContent-length:  
\r\n1234: blabla\nTo: to\_user@domain\n”[/content-length\s\*:\s\*(\d+)/i,  
1].to\_i  
=\> 1234

I’m trying to solve it by ading [^(\r|\n)] after (\d+) but I get  
nothing. Please, could you help me with this?

Thanks a lot in advance and best regards.
