dqcwl02022 2017-02-01 14:21
浏览 291

用制表符替换空格缩进

I am looking to replace 4 spaces at the start of a line to tabs, but nothing further when there is text present.

My initial regex of / {4}+/ or /[ ]{4}+/ for the sake of readability clearly worked but obviously any instance found with four spaces would be replaced.

$string  = '        this is some text -->    <-- are these tabs or spaces?';
$string .= "
    and this is another line singly indented";
// I wrote 4 spaces, a tab, then 4 spaces here but unfortunately it will not display
$string .= "
    \t    and this is third line with tabs and spaces";

$pattern = '/[ ]{4}+/';
$replace = "\t";

$new_str = preg_replace( $pattern , $replace , $string );

echo '<pre>'. $new_str .'</pre>';

This was an example of what I had originally, using the regex given the expression works perfectly with regards to the conversion but for the fact that the 4 spaces between the ----><---- are replaced by a tab. I am really looking to have text after indentation unaltered.

My best effort so far has been (^) start of line ([ ]{4}+) the pattern (.*?[;\s]*) anything up til the first non space \s

$pattern = '/^[ ]{4}+.*?[;\s]*/m';

which... almost works but for the fact that the indentation is now lost, can anybody help me understand what I am missing here?

[edit]

For clarity what I am trying to do is change the the start of text indentation from spaces to tabs, I really don't understand why this is confusing to anybody.

To be as clear as possible (using the value of $string above):

First line has 8 spaces at the start, some text with 4 spaces in the middle.
I am looking for 2 tabs at the start and no change to spaces in the text.

Second line has 4 spaces at the start.
I am looking to have only 1 tab at the start of the line.

Third line has 4 spaces, 1 tab and 4 spaces.
I am looking to have 3 tabs at the start of the line.
  • 写回答

2条回答 默认 最新

  • duanhuangyun3887 2017-02-01 15:50
    关注

    If you're not a regular expression guru, this will probably make most sense to you and be easier to adapt to similar use cases (this is not the most efficient code, but it's the most "readable" imho):

    // replace all regex matches with the result of applying
    // a given anonymous function to a $matches array
    function tabs2spaces($s_with_spaces) {
        // before anything else, replace existing tabs with 4 spaces
        // to permit homogenous translation
        $s_with_spaces = str_replace("\t", '    ', $s_with_spaces);
        return preg_replace_callback(
            '/^([ ]+)/m',
            function ($ms) {
                // $ms[0] - is full match
                // $ms[1] - is first (...) group fron regex
    
                // ...here you can add extra logic to handle
                // leading spaces not multiple of 4
    
                return str_repeat("\t", floor(strlen($ms[1]) / 4));
            },
            $s_with_spaces
        );
    }
    
    // example (using dots to make spaces visible for explaining)
    $s_with_spaces = <<<EOS
    no indent
    ....4 spaces indent
    ........8 spaces indent
    EOS;
    $s_with_spaces = str_replace('.', ' ');
    $s_with_tabs = tabs2spaces($s_with_spaces);
    

    If you want a performant but hard to understand or tweak one-liner instead, the solutions in the comments from the regex-gurus above should work :)


    P.S. In general preg_replace_callback (and its equivalent in Javascript) is a great "swiss army knife" of structured text processing. I have, shamefully, even writtent parsers to mini-languages using it ;)

    评论

报告相同问题?

悬赏问题

  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体
  • ¥88 实在没有想法,需要个思路
  • ¥15 MATLAB报错输入参数太多
  • ¥15 python中合并修改日期相同的CSV文件并按照修改日期的名字命名文件
  • ¥15 有赏,i卡绘世画不出
  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入