Is it possible to access the same argument twice in sprintf?

Asked

Viewed 113 times

6

In PHP times the function sprintf. With it we can format the values sequentially passed from the second parameter.

For example:

sprintf('Meu nome é %s e tenho %d anos de idade', 'Wallace', '26')

The exit will be

My name is Wallace and I’m 26 years old

But at a given moment I needed to have a functionality similar to those that exist in languages like Python or C#, where you can repeat in the format string one of the arguments passed.

For example in Python

 s = "Meu nome eh {0}. Sim, o meu nome eh {0}. Eu tenho {1} anos de idade"
 s.format('Wallace', 1)

The exit would be:

u"My name is Wallace. Yes, my name is Wallace. I am 1 years old"

Note that the parameter "Wallace" repeated itself without the need to pass it twice.

Using the sprintf PHP, I need a similar solution. It is possible to do the same operation as in Python PHP, using the function sprintf?

Note: I would like to know specifically about the function sprintf.In this case, user-created functions would not be welcome as a response.

2 answers

11


According to the function documentation sprintf, you must use the character $ preceded by a number, which represents the number of the argument you want to capture, and preceded by the desired formatting flag (for example, s, f or d).

The count of arguments starts from the number 1. The expression needs to be initialized by %, like all other ways used to format an argument in functions sprintf/printf.

Then, we could write the format string like this:

$tpl = 'Meu nome eh %1$s. Sim, o meu nome eh %1$s. Eu tenho %2$d anos de idade';

echo sprintf($tpl, 'Wallace', '26')

We read the code as follows:

%1$s "Replace this token with the first argument (Wallace) and format it as string.

%2$d "Replace this token with the second argument (26) and format it as an integer.

Functional example

  • 2

    I was surprised to learn that in PHP it had this :D

  • And I had even done a function for it '-'

  • 4

    @Guilhermelautert No one reads the manual! haha :P

  • @Laerte I look in the :D O.R.

2

The response of @Laerte is great and very correct, but I decided to leave two alternatives the answer just to make writing more practical tokens, resembling str.format python:

Suggestions 1:

I will post the example that the @Gumbo made/posted this function:

function format() {
    $args = func_get_args();
    if (count($args) == 0) {
        return;
    }

    if (count($args) == 1) {
        return $args[0];
    }

    $str = array_shift($args);
    $str = preg_replace_callback('/\\{(0|[1-9]\\d*)\\}/', create_function('$match', '$args = '.var_export($args, true).'; return isset($args[$match[1]]) ? $args[$match[1]] : $match[0];'), $str);
    return $str;
}

Use:

$str = 'Meu nome eh {0}.
        Sim, o meu nome eh {0}.
        Eu tenho {1} anos de idade.
        {0} {1} {1} {0}';

echo format($str, 'Wallace', 26);

Suggestions 2:

This I created now, is basically the vsprintf mixed with preg_replace

<?php
function format() {
    $args = func_get_args();
    if (empty($args)) {
        return null;
    }

    if (count($args) === 1) {
        return $args[0];
    }

    $str = array_shift($args);
    $str = preg_replace('#\{(\d+)\}#', '%$1\$s', $str);

    return vsprintf($str, $args);
}

Use:

The {0} is not supported, so always starts from 1

$str = 'Meu nome eh {1}.
        Sim, o meu nome eh {1}.
        Eu tenho {2} anos de idade.
        {1} {2} {2} {1}';

echo format($str, 'Wallace', 26);

Online example: http://ideone.com/0uf7cr

  • Remember my debug_backtrace? : D

  • @Guilhermelautert remember yes, I just do not remember the details hehehe :D

Browser other questions tagged

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