วิธีแทนที่ช่องว่างสีขาวหลายช่องด้วยช่องว่างเดียว


108

สมมติว่าฉันมีสตริงเช่น:

"Hello     how are   you           doing?"

ฉันต้องการฟังก์ชันที่เปลี่ยนช่องว่างหลายช่องให้เป็นช่องว่างเดียว

ดังนั้นฉันจะได้รับ:

"Hello how are you doing?"

ฉันรู้ว่าฉันสามารถใช้ regex หรือโทรได้

string s = "Hello     how are   you           doing?".replace("  "," ");

แต่ฉันจะต้องเรียกมันหลาย ๆ ครั้งเพื่อให้แน่ใจว่าช่องว่างตามลำดับทั้งหมดถูกแทนที่ด้วยช่องว่างเพียงอันเดียว

มีวิธีการในตัวสำหรับสิ่งนี้หรือไม่?


คุณช่วยชี้แจง: คุณกำลังจัดการกับช่องว่างหรือช่องว่าง "ทั้งหมด"?
Jon Skeet

และคุณต้องการเปลี่ยนช่องว่างที่ไม่ใช่ช่องว่างให้เป็นช่องว่างหรือไม่?
Jon Skeet

ฉันแค่หมายถึงช่องว่างทั้งหมดในซีรีย์ควรเป็นอย่างมากที่สุด
Matt

1
อาจซ้ำกันของstackoverflow.com/questions/206717/…
Michael Freidgeim

2 สิ่งที่ต้องพิจารณา: 1. char.IsWhiteSpace ประกอบด้วย carriage-return, linefeed เป็นต้น 2. 'whitespace' น่าจะถูกทดสอบด้วย Char.GetUnicodeCategory (ch) = Globalization.UnicodeCategory.SpaceSeparator
smirkingman

คำตอบ:


196
string cleanedString = System.Text.RegularExpressions.Regex.Replace(dirtyString,@"\s+"," ");

40
imo หลีกเลี่ยง regex หากคุณสบายใจกับพวกเขาคือการเพิ่มประสิทธิภาพก่อนกำหนด
Tim Hoolihan

8
หากแอปพลิเคชันของคุณไม่มีเวลาสำคัญก็สามารถจ่ายค่าโสหุ้ยในการประมวลผลได้ถึง 1 ไมโครวินาที
Daniel

16
โปรดทราบว่า 's' ไม่เพียงแทนที่ช่องว่างสีขาวเท่านั้น แต่ยังแทนที่อักขระบรรทัดใหม่ด้วย
Bart Kiers

12
จับได้ดีถ้าคุณต้องการเพียงแค่ช่องว่างให้เปลี่ยนรูปแบบเป็น "[] +"
Tim Hoolihan

9
คุณไม่ควรใช้ "{2,}" แทน "+" เพื่อหลีกเลี่ยงการแทนที่ช่องว่างเดียวหรือไม่
angularsen

52

คำถามนี้ไม่ง่ายอย่างที่ผู้โพสต์คนอื่น ๆ ทำออกมา (และอย่างที่ฉันเคยเชื่อมา แต่เดิม) - เพราะคำถามนั้นไม่ได้มีความแม่นยำเท่าที่ควร

มีความแตกต่างระหว่าง "ช่องว่าง" และ "ช่องว่าง" หากคุณเพียงหมายถึงช่องว่างแล้วคุณควรใช้ regex " {2,}"ของ หากคุณหมายถึงช่องว่างใด ๆนั่นเป็นเรื่องที่แตกต่างออกไป ช่องว่างทั้งหมดควรเปลี่ยนเป็นช่องว่างหรือไม่? จะเกิดอะไรขึ้นกับช่องว่างในตอนเริ่มต้นและจุดสิ้นสุด?

สำหรับเกณฑ์มาตรฐานด้านล่างฉันสันนิษฐานว่าคุณสนใจเฉพาะช่องว่างและคุณไม่ต้องการทำอะไรกับช่องว่างเดียวแม้ในช่วงเริ่มต้นและจุดสิ้นสุด

โปรดทราบว่าความถูกต้องนั้นสำคัญกว่าประสิทธิภาพเกือบตลอดเวลา ข้อเท็จจริงที่ว่าโซลูชัน Split / Join ลบช่องว่างที่นำหน้า / ต่อท้าย (แม้แต่ช่องว่างเดียว) นั้นไม่ถูกต้องเท่าที่ข้อกำหนดที่คุณระบุไว้ (ซึ่งแน่นอนว่าอาจไม่สมบูรณ์)

การใช้มาตรฐานMiniBench

using System;
using System.Text.RegularExpressions;
using MiniBench;

internal class Program
{
    public static void Main(string[] args)
    {

        int size = int.Parse(args[0]);
        int gapBetweenExtraSpaces = int.Parse(args[1]);

        char[] chars = new char[size];
        for (int i=0; i < size/2; i += 2)
        {
            // Make sure there actually *is* something to do
            chars[i*2] = (i % gapBetweenExtraSpaces == 1) ? ' ' : 'x';
            chars[i*2 + 1] = ' ';
        }
        // Just to make sure we don't have a \0 at the end
        // for odd sizes
        chars[chars.Length-1] = 'y';

        string bigString = new string(chars);
        // Assume that one form works :)
        string normalized = NormalizeWithSplitAndJoin(bigString);


        var suite = new TestSuite<string, string>("Normalize")
            .Plus(NormalizeWithSplitAndJoin)
            .Plus(NormalizeWithRegex)
            .RunTests(bigString, normalized);

        suite.Display(ResultColumns.All, suite.FindBest());
    }

    private static readonly Regex MultipleSpaces = 
        new Regex(@" {2,}", RegexOptions.Compiled);

    static string NormalizeWithRegex(string input)
    {
        return MultipleSpaces.Replace(input, " ");
    }

    // Guessing as the post doesn't specify what to use
    private static readonly char[] Whitespace =
        new char[] { ' ' };

    static string NormalizeWithSplitAndJoin(string input)
    {
        string[] split = input.Split
            (Whitespace, StringSplitOptions.RemoveEmptyEntries);
        return string.Join(" ", split);
    }
}

การทดสอบบางส่วน:

c:\Users\Jon\Test>test 1000 50
============ Normalize ============
NormalizeWithSplitAndJoin  1159091 0:30.258 22.93
NormalizeWithRegex        26378882 0:30.025  1.00

c:\Users\Jon\Test>test 1000 5
============ Normalize ============
NormalizeWithSplitAndJoin  947540 0:30.013 1.07
NormalizeWithRegex        1003862 0:29.610 1.00


c:\Users\Jon\Test>test 1000 1001
============ Normalize ============
NormalizeWithSplitAndJoin  1156299 0:29.898 21.99
NormalizeWithRegex        23243802 0:27.335  1.00

ตัวเลขแรกคือจำนวนการทำซ้ำครั้งที่สองคือเวลาที่ใช้และตัวเลขที่สามคือคะแนนที่กำหนดโดย 1.0 จะดีที่สุด

นั่นแสดงให้เห็นว่าอย่างน้อยในบางกรณี (รวมถึงนิพจน์นี้) นิพจน์ทั่วไปสามารถทำงานได้ดีกว่าโซลูชัน Split / Join ซึ่งบางครั้งก็มีระยะขอบที่สำคัญมาก

อย่างไรก็ตามหากคุณเปลี่ยนเป็นข้อกำหนด "ช่องว่างทั้งหมด" การแบ่ง / เข้าร่วมจะปรากฏว่าชนะ บ่อยครั้งที่ปีศาจอยู่ในรายละเอียด ...


1
การวิเคราะห์ที่ยอดเยี่ยม ดูเหมือนว่าเราทั้งคู่ถูกต้องกับองศาที่ต่างกัน รหัสในคำตอบของฉันนำมาจากฟังก์ชันที่ใหญ่กว่าซึ่งมีความสามารถในการทำให้ช่องว่างและ / หรืออักขระควบคุมเป็นปกติจากภายในสตริงและจากจุดเริ่มต้นและจุดสิ้นสุด
Scott Dorman

1
ด้วยอักขระช่องว่างที่คุณระบุในการทดสอบส่วนใหญ่ของฉัน regex และ Split / Join นั้นเท่าเทียมกัน - S / J มีประโยชน์เล็ก ๆ น้อย ๆ ในราคาของความถูกต้องและความซับซ้อน ด้วยเหตุผลเหล่านี้ฉันจึงชอบ regex มากกว่า อย่าเข้าใจฉันผิด - ฉันห่างไกลจาก regex fanboy แต่ฉันไม่ชอบเขียนโค้ดที่ซับซ้อนขึ้นเพื่อประสิทธิภาพโดยไม่ได้ทดสอบประสิทธิภาพก่อน
Jon Skeet

NormalizeWithSplitAndJoin จะสร้างขยะมากขึ้นเป็นการยากที่จะบอกได้ว่าปัญหาที่แท้จริงจะได้รับเวลา GC มากขึ้นหรือไม่จากนั้นจึงแบนด์มาร์ก
Ian Ringrose

@IanRingrose ขยะแบบไหนสร้างได้?
Dronz

18

Expressoin ปกติจะเป็นวิธีที่ง่ายที่สุด หากคุณเขียน regex ด้วยวิธีที่ถูกต้องคุณจะไม่ต้องโทรหลายครั้ง

เปลี่ยนเป็นสิ่งนี้:

string s = System.Text.RegularExpressions.Regex.Replace(s, @"\s{2,}", " "); 

ปัญหาหนึ่งของฉัน@"\s{2,}"คือไม่สามารถแทนที่แท็บเดียวและอักขระช่องว่าง Unicode อื่นด้วยช่องว่างได้ หากคุณกำลังจะแทนที่ 2 แท็บด้วยช่องว่างคุณควรจะแทนที่ 1 แท็บด้วยช่องว่าง @"\s+"จะทำเพื่อคุณ
David Specht

17

แม้ว่าคำตอบที่มีอยู่จะใช้ได้ แต่ฉันต้องการชี้ให้เห็นแนวทางหนึ่งที่ไม่ได้ผล:

public static string DontUseThisToCollapseSpaces(string text)
{
    while (text.IndexOf("  ") != -1)
    {
        text = text.Replace("  ", " ");
    }
    return text;
}

สิ่งนี้สามารถวนซ้ำได้ตลอดไป ทุกคนสนใจที่จะเดาว่าทำไม? (ฉันเพิ่งเจอสิ่งนี้เมื่อถูกถามเป็นคำถามกลุ่มข่าวเมื่อไม่กี่ปีที่ผ่านมา ... มีคนพบว่าเป็นปัญหาจริงๆ)


ฉันคิดว่าฉันจำคำถามนี้ได้ในขณะที่ถามกลับใน SO IndexOf ละเว้นอักขระบางตัวที่แทนที่ไม่ได้ ดังนั้นพื้นที่สองเท่าจึงอยู่ที่นั่นเสมอไม่เคยถูกลบออก
Brandon

19
เป็นเพราะ IndexOf ละเว้นอักขระ Unicode บางตัวข้อผิดพลาดเฉพาะในกรณีนี้คืออักขระเอเชีย iirc อืมตัวเชื่อมที่ไม่ใช่ความกว้างเป็นศูนย์ตาม Google
ahawker

ฉันได้เรียนรู้ว่าวิธีที่ยาก :( stackoverflow.com/questions/9260693/…
Antonio Bakula

ฉันเรียนรู้วิธีที่ยาก โดยเฉพาะกับผู้เข้าร่วมที่ไม่ใช่ Zero Width สองตัว (\ u200C \ u200C) IndexOf ส่งคืนดัชนีของ "double space" นี้ แต่ Replace จะไม่แทนที่ ฉันคิดว่าเป็นเพราะสำหรับ IndexOf คุณต้องระบุ StringComparsion (Ordinal) เพื่อให้ทำงานเหมือนกับ Replace วิธีนี้ทั้งสองจะไม่พบ "ช่องว่างคู่" เพิ่มเติมเกี่ยวกับ StringComparsion docs.microsoft.com/en-us/dotnet/api/…
Martin Brabec

4

ดังที่ได้กล่าวไปแล้วสิ่งนี้ทำได้อย่างง่ายดายโดยนิพจน์ทั่วไป ฉันจะเพิ่มว่าคุณอาจต้องการเพิ่ม. trim () เพื่อกำจัดช่องว่างนำหน้า / ต่อท้าย


4

นี่คือโซลูชันที่ฉันทำงานด้วย ไม่มี RegEx และ String.Split

public static string TrimWhiteSpace(this string Value)
{
    StringBuilder sbOut = new StringBuilder();
    if (!string.IsNullOrEmpty(Value))
    {
        bool IsWhiteSpace = false;
        for (int i = 0; i < Value.Length; i++)
        {
            if (char.IsWhiteSpace(Value[i])) //Comparion with WhiteSpace
            {
                if (!IsWhiteSpace) //Comparison with previous Char
                {
                    sbOut.Append(Value[i]);
                    IsWhiteSpace = true;
                }
            }
            else
            {
                IsWhiteSpace = false;
                sbOut.Append(Value[i]);
            }
        }
    }
    return sbOut.ToString();
}

คุณสามารถ:

string cleanedString = dirtyString.TrimWhiteSpace();

4

น้ำยาล้างช่องว่างด่วนพิเศษโดย Felipe Machado (แก้ไขโดย RW สำหรับการลบหลายช่องว่าง)

static string DuplicateWhiteSpaceRemover(string str)
{
    var len = str.Length;
    var src = str.ToCharArray();
    int dstIdx = 0;
    bool lastWasWS = false; //Added line
    for (int i = 0; i < len; i++)
    {
        var ch = src[i];
        switch (ch)
        {
            case '\u0020': //SPACE
            case '\u00A0': //NO-BREAK SPACE
            case '\u1680': //OGHAM SPACE MARK
            case '\u2000': // EN QUAD
            case '\u2001': //EM QUAD
            case '\u2002': //EN SPACE
            case '\u2003': //EM SPACE
            case '\u2004': //THREE-PER-EM SPACE
            case '\u2005': //FOUR-PER-EM SPACE
            case '\u2006': //SIX-PER-EM SPACE
            case '\u2007': //FIGURE SPACE
            case '\u2008': //PUNCTUATION SPACE
            case '\u2009': //THIN SPACE
            case '\u200A': //HAIR SPACE
            case '\u202F': //NARROW NO-BREAK SPACE
            case '\u205F': //MEDIUM MATHEMATICAL SPACE
            case '\u3000': //IDEOGRAPHIC SPACE
            case '\u2028': //LINE SEPARATOR
            case '\u2029': //PARAGRAPH SEPARATOR
            case '\u0009': //[ASCII Tab]
            case '\u000A': //[ASCII Line Feed]
            case '\u000B': //[ASCII Vertical Tab]
            case '\u000C': //[ASCII Form Feed]
            case '\u000D': //[ASCII Carriage Return]
            case '\u0085': //NEXT LINE
                if (lastWasWS == false) //Added line
                {
                    src[dstIdx++] = ' '; // Updated by Ryan
                    lastWasWS = true; //Added line
                }
                continue;
            default:
                lastWasWS = false; //Added line 
                src[dstIdx++] = ch;
                break;
        }
    }
    return new string(src, 0, dstIdx);
}

เกณฑ์มาตรฐาน ...

|                           | Time  |   TEST 1    |   TEST 2    |   TEST 3    |   TEST 4    |   TEST 5    |
| Function Name             |(ticks)| dup. spaces | spaces+tabs | spaces+CR/LF| " " -> " "  | " " -> " " |
|---------------------------|-------|-------------|-------------|-------------|-------------|-------------|
| SwitchStmtBuildSpaceOnly  |   5.2 |    PASS     |    FAIL     |    FAIL     |    PASS     |    PASS     |
| InPlaceCharArraySpaceOnly |   5.6 |    PASS     |    FAIL     |    FAIL     |    PASS     |    PASS     |
| DuplicateWhiteSpaceRemover|   7.0 |    PASS     |    PASS     |    PASS     |    PASS     |    PASS     |
| SingleSpacedTrim          |  11.8 |    PASS     |    PASS     |    PASS     |    FAIL     |    FAIL     |
| Fubo(StringBuilder)       |    13 |    PASS     |    FAIL     |    FAIL     |    PASS     |    PASS     |
| User214147                |    19 |    PASS     |    PASS     |    PASS     |    FAIL     |    FAIL     | 
| RegExWithCompile          |    28 |    PASS     |    FAIL     |    FAIL     |    PASS     |    PASS     |
| SwitchStmtBuild           |    34 |    PASS     |    FAIL     |    FAIL     |    PASS     |    PASS     |
| SplitAndJoinOnSpace       |    55 |    PASS     |    FAIL     |    FAIL     |    FAIL     |    FAIL     |
| RegExNoCompile            |   120 |    PASS     |    PASS     |    PASS     |    PASS     |    PASS     |
| RegExBrandon              |   137 |    PASS     |    FAIL     |    PASS     |    PASS     |    PASS     |

หมายเหตุมาตรฐาน: Release Mode, no-debugger attached, i7 processor, avg of 4 run, only short strings test

SwitchStmtBuildSpaceOnly โดยFelipe Machado 2015 และแก้ไขโดย Sunsetquest

InPlaceCharArraySpaceOnly โดยFelipe Machado 2015 และแก้ไขโดย Sunsetquest

SwitchStmtBuild โดยFelipe Machado 2015 และแก้ไขโดย Sunsetquest

SwitchStmtBuild2 โดยFelipe Machado 2015 และแก้ไขโดย Sunsetquest

SingleSpacedTrim โดยDavid S 2013

Fubo (StringBuilder) โดยfubo 2014

SplitAndJoinOnSpace โดยJon Skeet 2009

RegExWithCompile โดยJon Skeet 2009

User214147 โดยuser214147

RegExBrandon โดยBrandon

RegExNoCompile โดยTim Hoolihan

Benchmark code อยู่ใน Github


1
ยินดีที่ได้เห็นบทความของฉันอ้างอิงที่นี่! (ฉันชื่อเฟลิเป้มาชาโด) ฉันกำลังจะอัปเดตโดยใช้เครื่องมือเปรียบเทียบที่เหมาะสมที่เรียกว่า BenchmarkDotNet! ฉันจะพยายามตั้งค่าให้ทำงานในทุกช่วงเวลา (ตอนนี้เรามี DOT NET CORE และสิ่งที่ชอบ ...
Loudenvier

1
@Loudenvier - ทำได้ดีมากในเรื่องนี้ ของคุณเร็วที่สุดเกือบ 400%! .Net Core เป็นเหมือนการเพิ่มประสิทธิภาพฟรี 150-200% ประสิทธิภาพใกล้เคียงกับ c ++ มากขึ้น แต่โค้ดง่ายกว่ามาก ขอบคุณสำหรับความคิดเห็น
Sunsetquest

2
สิ่งนี้จะเว้นวรรคเท่านั้นไม่ใช่อักขระช่องว่างอื่น ๆ บางทีคุณอาจต้องการ char.IsWhiteSpace (ch) แทน src [i] == '\ u0020' ฉันสังเกตเห็นว่ามีการแก้ไขโดยชุมชน พวกเขาทำให้มันขึ้น?
Evil Pigeon

3

ฉันกำลังแบ่งปันสิ่งที่ฉันใช้เพราะดูเหมือนว่าฉันมีบางอย่างที่แตกต่างออกไป ฉันใช้มันมาระยะหนึ่งแล้วและมันก็เร็วพอสำหรับฉัน ฉันไม่แน่ใจว่ามันซ้อนทับกันอย่างไร ฉันใช้มันในโปรแกรมเขียนไฟล์ที่ใช้ตัวคั่นและเรียกใช้ข้อมูลขนาดใหญ่ทีละช่อง

    public static string NormalizeWhiteSpace(string S)
    {
        string s = S.Trim();
        bool iswhite = false;
        int iwhite;
        int sLength = s.Length;
        StringBuilder sb = new StringBuilder(sLength);
        foreach(char c in s.ToCharArray())
        {
            if(Char.IsWhiteSpace(c))
            {
                if (iswhite)
                {
                    //Continuing whitespace ignore it.
                    continue;
                }
                else
                {
                    //New WhiteSpace

                    //Replace whitespace with a single space.
                    sb.Append(" ");
                    //Set iswhite to True and any following whitespace will be ignored
                    iswhite = true;
                }  
            }
            else
            {
                sb.Append(c.ToString());
                //reset iswhitespace to false
                iswhite = false;
            }
        }
        return sb.ToString();
    }

2

ด้วยการใช้โปรแกรมทดสอบที่ Jon Skeet โพสต์ฉันพยายามดูว่าฉันจะทำให้ลูปที่เขียนด้วยมือทำงานได้เร็วขึ้นหรือไม่
ฉันสามารถเอาชนะ NormalizeWithSplitAndJoin ได้ทุกครั้ง แต่เอาชนะ NormalizeWithRegex ด้วยอินพุต 1,000, 5 เท่านั้น

static string NormalizeWithLoop(string input)
{
    StringBuilder output = new StringBuilder(input.Length);

    char lastChar = '*';  // anything other then space 
    for (int i = 0; i < input.Length; i++)
    {
        char thisChar = input[i];
        if (!(lastChar == ' ' && thisChar == ' '))
            output.Append(thisChar);

        lastChar = thisChar;
    }

    return output.ToString();
}

ฉันไม่ได้ดูรหัสเครื่องที่กระวนกระวายใจ แต่ฉันคาดว่าปัญหาคือเวลาที่ใช้ในการโทรไปยัง StringBuilder ผนวก () และเพื่อให้ดีขึ้นมากจะต้องใช้รหัสที่ไม่ปลอดภัย

ดังนั้น Regex.Replace () เร็วมากและยากที่จะเอาชนะ !!


2

VB.NET

Linha.Split(" ").ToList().Where(Function(x) x <> " ").ToArray

ค#

Linha.Split(" ").ToList().Where(x => x != " ").ToArray();

เพลิดเพลินไปกับพลังของ LINQ = D


เป๊ะ! สำหรับฉันนี่เป็นแนวทางที่สง่างามที่สุดเช่นกัน ดังนั้นสำหรับบันทึกใน C # จะเป็น:string.Join(" ", myString.Split(' ').Where(s => s != " ").ToArray())
Efrain

1
ปรับปรุงเล็กน้อยในการSplitจับช่องว่างทั้งหมดและลบWhereข้อ:myString.Split(null as char[], StringSplitOptions.RemoveEmptyEntries)
เดวิด

1
Regex regex = new Regex(@"\W+");
string outputString = regex.Replace(inputString, " ");

สิ่งนี้จะแทนที่อักขระที่ไม่ใช่คำทั้งหมดด้วยช่องว่าง ดังนั้นมันจะแทนที่สิ่งต่างๆเช่นวงเล็บและเครื่องหมายคำพูดเป็นต้นซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ
Herman

0

ทางออกที่เล็กที่สุด:

var regExp = / \ s + / g, newString = oldString.replace (regExp, '');


0

คุณสามารถลองสิ่งนี้:

    /// <summary>
    /// Remove all extra spaces and tabs between words in the specified string!
    /// </summary>
    /// <param name="str">The specified string.</param>
    public static string RemoveExtraSpaces(string str)
    {
        str = str.Trim();
        StringBuilder sb = new StringBuilder();
        bool space = false;
        foreach (char c in str)
        {
            if (char.IsWhiteSpace(c) || c == (char)9) { space = true; }
            else { if (space) { sb.Append(' '); }; sb.Append(c); space = false; };
        }
        return sb.ToString();
    }

0

กลุ่มเปลี่ยนให้ impler แนวทางการแก้ไขปัญหาการเปลี่ยนหลายพื้นที่สีขาวตัวอักษรที่มีเดียวกันหนึ่งเดียว:

    public static void WhiteSpaceReduce()
    {
        string t1 = "a b   c d";
        string t2 = "a b\n\nc\nd";

        Regex whiteReduce = new Regex(@"(?<firstWS>\s)(?<repeatedWS>\k<firstWS>+)");
        Console.WriteLine("{0}", t1);
        //Console.WriteLine("{0}", whiteReduce.Replace(t1, x => x.Value.Substring(0, 1))); 
        Console.WriteLine("{0}", whiteReduce.Replace(t1, @"${firstWS}"));
        Console.WriteLine("\nNext example ---------");
        Console.WriteLine("{0}", t2);
        Console.WriteLine("{0}", whiteReduce.Replace(t2, @"${firstWS}"));
        Console.WriteLine();
    }

โปรดสังเกตว่าตัวอย่างที่สองยังคงเป็นโสด\nในขณะที่คำตอบที่ยอมรับจะแทนที่ท้ายบรรทัดด้วยช่องว่าง

หากคุณจำเป็นต้องเปลี่ยนใด ๆรวมกันของตัวอักษรพื้นที่สีขาวกับคนแรกเพียง แต่เอากลับอ้างอิง\kจากรูปแบบ


0

การใช้นิพจน์ทั่วไปเพื่อแทนที่ช่องว่างสีขาว 2 ช่องขึ้นไปด้วยช่องว่างเดียวก็เป็นทางออกที่ดีเช่นกัน

เรากำลังใช้รูปแบบนิพจน์ทั่วไปเป็น“ \ s +

  • จับคู่ช่องว่างแท็บบรรทัดใหม่การคืนค่าขนส่งฟีดแบบฟอร์มหรือแท็บแนวตั้ง

  • "+" กล่าวว่าเกิดเหตุการณ์อย่างน้อยหนึ่งครั้ง

ตัวอย่าง Regex

String blogName = "  Sourav .  Pal.   "

 String nameWithProperSpacing = blogName.replaceAll("\\s+", " ");   
System.out.println( nameWithProperSpacing );

-1

ไม่มีวิธีใดในตัวเพื่อทำสิ่งนี้ คุณสามารถลองสิ่งนี้:

private static readonly char[] whitespace = new char[] { ' ', '\n', '\t', '\r', '\f', '\v' };
public static string Normalize(string source)
{
   return String.Join(" ", source.Split(whitespace, StringSplitOptions.RemoveEmptyEntries));
}

การดำเนินการนี้จะลบช่องว่างที่นำหน้าและต่อท้ายตลอดจนยุบช่องว่างภายในให้เหลือเพียงอักขระช่องว่างเดียว หากคุณต้องการเพียงแค่ยุบช่องว่างจริงๆการแก้ปัญหาโดยใช้นิพจน์ทั่วไปจะดีกว่า มิฉะนั้นวิธีนี้จะดีกว่า (ดูการวิเคราะห์ของ Jon Skeet)


7
หากการแสดงออกปกติจะรวบรวมและเก็บไว้ฉันไม่แน่ใจว่ามีค่าใช้จ่ายมากขึ้นกว่าการแยกและเข้าร่วมซึ่งสามารถสร้างการโหลดของสตริงขยะกลาง คุณได้ทำการเปรียบเทียบอย่างรอบคอบของทั้งสองวิธีก่อนที่จะคิดว่าวิธีของคุณเร็วขึ้นหรือไม่?
Jon Skeet

1
ไม่มีการประกาศช่องว่างที่นี่
Tim Hoolihan

3
เมื่อพูดถึงค่าใช้จ่ายทำไมคุณถึงเรียกร้องsource.ToCharArray()และทิ้งผลลัพธ์บนโลกนี้?
Jon Skeet

2
และเรียกร้องToCharArray()ผลลัพธ์ของสตริงเข้าร่วมเพียงเพื่อสร้างสตริงใหม่ ... ว้าวสำหรับการโพสต์ที่บ่นเรื่องค่าใช้จ่ายเป็นเรื่องที่น่าทึ่ง -1.
Jon Skeet

1
โอ้และสมมติว่าwhitespaceเป็นnew char[] { ' ' }นี้จะให้ผลที่ไม่ถูกต้องถ้าสายป้อนเริ่มต้นหรือสิ้นสุดลงด้วยการเว้นวรรค
Jon Skeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.