Substring from an escape character onwards - postgresql

I'm using PostgreSQL and I need to truncate a text string, I need to show from an escape character (:) onwards.
I'm trying something like that:
SELECT SUBSTRING ('CATEGORIA DE TRABAJOS: EJECUTIVO' FROM '%#":#"%' FOR '#');

t=# select split_part('CATEGORIA DE TRABAJOS: EJECUTIVO',':',2);
split_part
------------
EJECUTIVO
(1 row)
just split by first found delimiter?..

Related

how to remove backslash from a string using redshift?

How to remove backslash in redshift?
For example:
1\234
I want only:
1 234
I have tried regexp_replace function but it didn't work.
REPLACE(string1, old_chars, new_chars)
select replace('1\\2345','\\',' ')
http://docs.aws.amazon.com/redshift/latest/dg/r_REPLACE.html

Preserving spaces for character type in SELECT

Is it possible to preserve the padded spaces in character(N) type in select?
That is
SELECT left(' 10 '::character(5), 3), right(' 10 '::character(5), 2)
should return
' 10', ' '
but it returns
' 10', '10'
Can I somehow tell the system to preserve all the spaces and don't do any trimming?
I'm using PostgreSQL 9.6
Thanks
https://www.postgresql.org/docs/current/static/functions-string.html
right(str text, n int) Return last n characters in the string.
When n is negative, return all but first |n| characters.
which actually happens when you use variable length string:
t=# SELECT left(' 10 '::character(5), 3), right(' 10 '::character varying(5), 2);
-[ RECORD 1 ]
left | 10
right |
it returns two spaces
As Abelisto says in his answer, the documentation clearly states on character data type:
Trailing spaces are removed when converting a character value to one
of the other string types.
so right and left will remove spaces by their definition. to avoid it you need to use varying text
update
when you explicitly cast char(5) to text, spaces are removed - to avoid it, you can use function that does not implicitly cast any string to text before processing and thus respecting your ending spaces, eg concat:
t=# with a(v) as (select ' 10 '::character(5))
, monkey_cast as (select concat(v,'') v from a)
select quote_ident(v),left(v,3), right(v,3) from monkey_cast;
quote_ident | left | right
-------------+------+-------
" 10 " | 10 | 0
(1 row)
It is "feature" of the character type - it considers trailing spaces as insignificant:
select quote_ident(' 10 '::char(5)), quote_ident(' 10 '::varchar(5));
┌─────────────┬─────────────┐
│ quote_ident │ quote_ident │
╞═════════════╪═════════════╡
│ " 10" │ " 10 " │
└─────────────┴─────────────┘
So if your care about trailing spaces - use varchar or text type instead.

TRIM not works with lines and tabs of a xpath in PostgreSQL?

With this query
SELECT trim(title) FROM (
SELECT
unnest( xpath('//p[#class="secTitle1"]', xmlText )::varchar[] ) AS title
FROM t1
) as t2
and XML input text with lines and spaces,
<root>
...
<p class="x">
text text
text text
</p><p> ...</p>
...
</root>
The trim() have no effect (!). It is a PostgreSQL bug? How to apply fn:normalize-space() with the XPath? I need something like "WHERE title is not null"? (Oracle is simpler...) How to do this simple query with PostreSQL?
Workaround
I need a well-configured build-in function, not a workaround... But I need to work and to show results, so I am using regular expression...
SELECT id, TRIM(regexp_replace(tit, E'[\\n\\r\\t ]+', ' ', 'g')) AS tit
FROM (
SELECT
id, -- xpath returns array of 1, 2, or more strings
unnest( xpath('//p[#class="secTitle1"]', texto )::VARCHAR[] ) AS tit
FROM t
) AS tmp
So, a "only simple space trim" is not friendly, not util (!).
EDIT after #mu comment
I try
SELECT id, TRIM(tit, E'\\n\\r\\t') AS tit
and
SELECT id, TRIM(tit, '\n\r\t') AS tit
both NOT WORKs.
QUESTION REMAINS:
there are no TRIM-option or postgresql configuration to say to TRIM work as it is required?
can I use normalize-space() at xpath? How?
I am using PostgreSQL 9.1, need to upgrade?
It works in 9.2, and it works on 8.4 too.
postgres=# select trim(unnest(string_to_array(e'\t\tHello\n\t\tHello\n\t\tHello', e'\n')), e'\t');
btrim
-------
Hello
Hello
Hello
(3 rows)
your regexp replace any char \n or \r or \t, but trim working with string "\n\r\t". It has different meaning than you expect.

PostgreSQL substring

I have a function and I want to get a string between two strings where the first one is "Start" and the second one is the new line character.
I mean: From "Start blablabla \n" I only want "blablabla".
I've tried this, but it doesn't work:
select substring(test from 'Start(.+)\n') into vtest;
How can I identify the newline character??
Thanks!
It needs to be double-escaped:
test=> select substring('foo
bar' from E'\\A(.*)\\r?\\n');
substring
-----------
foo
(1 row)
Alternative version:
select substring('foo
bar' from E'\\A.*(?=\\r?\\n)');
The $ symbol matches the string end:
select substring('Start123' from 'Start(.+)$');
substring
-----------
123

replace string with split_part function

I want to replace the first word before delimeter ' ,' with ' 0, the first word ')
select replace('tab,graph,map', split_part('tab,graph', ',', 1) like 'tab','0, tab')
ERROR: function replace(unknown, boolean, unknown) does not exist
LINE 1: select replace('tab,graph,map', split_part('tab,graph', ',',...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
The replace function replaces all occurrences of the string so you have to make sure the string to replace is unique or use something else. However, regexp_replace only replaces the first occurrence by default so you can use that; your question is a little unclear about what the expected output is but maybe this is is what you're looking for:
=> select regexp_replace('tab,graph,map', ',', '0,');
regexp_replace
----------------
tab0,graph,map
Or this one:
=> select regexp_replace('tab,graph,map', 'tab,', '0,');
regexp_replace
----------------
0,graph,map
Or maybe even this:
=> select regexp_replace('tab,graph,map', 'tab,', '0,,');
regexp_replace
----------------
0,,graph,map
you need to cast, since the function expects replace(text, text, text) and does not know how to handle your literal strings calling them unknown...
cast('tab,graph,map' AS text)
also the 2nd param is a LIKE comparison ? which returns boolean, but the function replace expects it to be the delimiter.
CAST(split_part('tab,graph', ',', 1) AS text)
finally the last param (same problem as the first)
cast('0, tab' AS text)
of course if you really just want to prepend '0, ' to your string, 'tab,graph,map' you could just do that...
SELECT '0, ' || 'tab,graph,map' ;