How to take part of a String up to a specified character?

Asked

Viewed 4,467 times

5

I would like a Javascript method that takes part of a String up to a certain point (character) from it. In this case I would specify a character and only be taken part of the String until the character I specified.

  • I wouldn’t want to use the methods substring, indexOf or the split. Because they require me to do this in more than one line of code (using array or indexes) and, in my specific problem, it needs to be done in a single line.

Example of what I would need:

let frase = "99 troços";

//Eu precisaria disso (que está abaixo) só que sem utilizar outras linhas de código antes da variável armazenarValor.
let armazenarValor = "99"; //Ignoraria o espaço e o 'troços'.


//Eu precisaria que ficasse algo assim
let armazenarValor = pegarAteEspaco(frase, " ");
//Imaginemos que pegarAteEspaco() fosse um método JavaScript que pegasse uma String até determinado caracter.
//Eu só gostaria de pegar o "99" e ignorar o resto.

  • I couldn’t do a function for that either.
  • In PHP there are methods that do this. But I would like to do in JS.
  • I saw some things here at the Stack Overflow, but most are using substring, split or indexOf.
  • Maybe there isn’t something native to JS made exactly for this.
  • 4

    Without these functions you need a loop, which complicates solving in a row (weirder requirement!) Using substring + index you can do in a row...

  • Thank you, bfavareto. The question of a regular expression, quoted in the reply of Luiz Felipe, seemed to me very interesting. But I don’t think it would be in a single line either. I actually don’t think there’s anything native to Javascript that does this.

  • 3

    But why not just let trecho = frase.substring(0, frase.indexOf(' '))?

  • Soon I will test your answer correctly, Luiz Felipe. Working out, I give the vote and accept her ;D

  • 2

    Complementing @bfavaretto, you can also do let valor = frase.split(' ')[0]. That’s just a line...

  • maybe it will also work, @bfavaretto. I will test in a little while and return to you the result.

  • 1

    Ah, I get it... You’re running this code on one of these courses/challenges sites, right? Only they put these absurd requirements, how to solve...

  • 2

    When writing code in "one line," you will often be giving up code readability for a factor that rarely "matters" in the long run. Readability is usually much more important than the number of lines. I think it’s worth reviewing the need to do in "one line"... :)

  • Worse than not, @bfavaretto. It’s a necessity you painted here at work. I’m using Chart Js and painted some bullshit here that I had to do to solve the problem.

  • @Luizfelipe, I don’t usually do this. It was the need even. It’s actually the first time I do this.

  • Worse than now they’ve had a lot of answers they might solve. I will give preference to those who responded first to those that I can really understand. I don’t know how to use regular expression, but @Luizfelipe’s reply was the first.

  • 3

    You must accept the one that best solved the problem for you, regardless of the order :-)

  • So the reply from @hkotsubo served me nicely, I even tried to add a few numbers after space but really only came out the 99. But I found this question of parseint() somewhat sinister for such a situation. Luiz Felipe’s answer also served me well. But I know nothing about regular expression (And using something in the code you don’t understand is kind of boring) and I don’t know if it could open up any loopholes in my case. The two helped me a lot. I am in doubt which answer to accept. Any of the choices, would be unfair to the other.

  • 2

    It’s up to you to choose any of them. In your case, it’s interesting to read this discussion: https://pt.meta.stackoverflow.com/q/1540/112052 - particularly, I don’t think it would be "unfair" to me since Felipe’s other response was also good (and this use of parseInt I don’t like, I don’t know, I prefer not to depend on these "magic"). Anyway, you decide :-)

  • Dilemma, man. I don’t think parseint is the right way for this question of mine, but it worked. The regular expression worked, but I understood nothing and I do not know if other users, half laypeople like me, would understand too. Have you seen that meme where the guy gets in doubt between two buttons to press ? That’s how I am now. Rs

Show 10 more comments

3 answers

8


You can use a regular expression to do this:

const string = '99 troços';

const [, match] = string.match(/(\S+) /) || [];

console.log(match);

In the above regular expression, we create a capture group to get the desired value. Within this group, we use \S+ to give match in one or more characters other than white space (such as spaces, line breaks, tabs, etc.). Then we hope that always after this capture group, there is a space.

Like the String.prototype.match can return null if regular expression does not find occurrences, I used a fallback at the end, so that a array always be returned, and always be able to do the de-structuring.


You can also write the code in a single line:

const [, match] = '99 troços'.match(/(\S+) /) || [];
console.log(match);

// Ou se você realmente quiser em uma linha mesmo:
console.log(('99 troços'.match(/(\S+) /) || [])[1]);

But I really don’t know why you would want to do that, since it makes the code quite unreadable, at least using this form. As placed in the comments (here, by @bfavaretto; and here, by @hkotsubo), there are other more "elegant" ways to do this in a single line.

  • 4

    Just remembering that the \S ignores several other characters besides space, such as TAB and line breaks (the complete list is in the documentation). For the case of the question it makes no difference because the string does not have these other characters, but how is the record. If you want to ignore only spaces, can use [^ ] (notice that there is a gap between the ^ and the ]

5

Well, there is an alternative - in my opinion, kind of "ugly" - and that "serves" specifically for the case of the question (which has numbers at the beginning). I leave it here as a curiosity:

let frase = "99 troços";
let valor = parseInt(frase);
console.log(valor); // 99

That just "works" because according to the documentation of parseInt:

If parseInt Encounters a Character that is not a numeral in the specified Radix, it ignores it and all succeeding characters and Returns the integer value Parsed up to that point.

In free translation:

If parseInt finds a character that is not a numeral in the specified base, it ignores this and all of the following characters and returns the integer that was read up to that point.

I mean, he reads the 99 and when you find the space, stop reading. At the end the result is 99.


Of course, if the situation is different (string does not start with numbers, etc.), then it is better to use the solutions of the other answers. Although for these cases I still prefer to use substring, split and indexOf.

  • That’s cowardice, isn’t it ?

  • @Jason-Theinternship. I wouldn’t say cowardice, I’m just taking advantage of the way the function was implemented :-) Although in production code I would use substring or split to clarify what is being done...

  • 1

    I chose the other one, @hkotsubo, but your answer would also be useful to me. Thank you!

4

I did not understand this requirement not to use the method String.prototype.split() is a native method of language splits a String object into an array of strings by separating the string into substrings.

In this case instead of searching for separations just limit the action of the method to the first occurrence of the separator through the parameter limite.

let texto = "99 troços a 99 centavos ";

console.log(pegarAteEspaco(texto, " "));

function pegarAteEspaco(frase, separador) {
  return frase.split(separador, 1)[0]
}

Same code on one line:

console.log("99 troços a 99 centavos ".split(" ", 1)[0])
  • Yes, @Augusto Vasques. Your job performed legal. But as I had mentioned in the description of the question, I need something that would only waste a line of code and not use function. But still I appreciate your time to try to help my problem.

  • @Jason-Theinternship. If the question is a line just use this console.log("99 troços a 99 centavos ".split(" ", 1)[0])

  • Yes, Augusto. Your situation was also useful.

  • I chose the other answer, because the guy answered first and also because I had mentioned, in the description of the question, that it should not be split. But your answer would also be useful to me. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.