c# - 추출 - 정규표현식 테스트 사이트




정규 표현식으로 단어 배치 (4)

JS의 내 솔루션 :

function wordWrap(s, width) {
  var r = '(?:(.{1,' + width + '})[ \\r\\t]+|(.{' + width + '}))(?!$)';
  r = new RegExp(r, 'g');
  // console.log(r);
  return s.replace(r, '$1$2\n');
}

명료 한 편집 - 여러 단계에서 이것을 수행하거나 LINQ 또는 바닐라 C # 문자열 조작을 사용하는 방법이 있다는 것을 알고 있습니다. 하나의 정규식 호출을 사용하는 이유는 복잡한 정규식 패턴으로 연습을하기 때문입니다. - END EDIT

단어 줄 바꿈을 수행하는 단일 정규 표현식을 작성하려고합니다. 원하는 출력에 매우 가깝지만 작동시킬 수는 없습니다.

Regex.Replace(text, @"(?<=^|\G)(.{1,20}(\s|$))", "$1\r\n", RegexOptions.Multiline)

이것은 너무 긴 행에 대해 올바르게 단어를 줄 바꿈하지만 이미있을 때 줄 바꿈을 추가합니다.

입력

"This string is really long. There are a lot of words in it.\r\nHere's another line in the string that's also very long."

예상 결과

"This string is \r\nreally long. There \r\nare a lot of words \r\nin it.\r\nHere's another line \r\nin the string that's \r\nalso very long."

실제 출력

"This string is \r\nreally long. There \r\nare a lot of words \r\nin it.\r\n\r\nHere's another line \r\nin the string that's \r\nalso very long.\r\n"

입력이 이미 줄 바꿈을 한 문장과 마지막에 넣은 "\ r \ n"문장 사이에 이중 "\ r \ n"을 적어 둡니다.

조건부로 다른 대체 패턴을 적용 할 수있는 방법이 있습니까? IE 일치 항목이 "\ r \ n"으로 끝나면 "$ 1"패턴을 사용하고, 그렇지 않으면 "$ 1 \ r \ n"패턴을 사용하십시오.

다음은 시작점으로 사용한 공백이없는 문자열을 래핑하는 것과 비슷한 질문에 대한 링크입니다. 끊김없는 텍스트를 찾고 공백을 삽입하는 정규식


다음은 이러한 훌륭한 아이디어를 결합한 솔루션입니다. 나는 처음부터 정규 표현식을 작성하여 sln이 제공 한 것과 매우 유사하다는 것을 알았지 만, 조금 더 짧아서 아마도 더 적은 역 추적을 수행합니다.

# assuming a max line length of 16
(?:
    [^\r\n]{1,16}(?=\s|$)       # non-linebreaking characters followed by a space 
                                #    or end-of-string, up to the max line length
    |[^\r\n]{16}                # Or for really long words: a sequence of non-breaking  
                                #    characters exactly the line length
    |(?<=\n)\r?\n               # Or blank lines: a line break following another line break.  This works for \n or \r\n styles.
)

LB와 마찬가지로 확장 메서드 인 WordWrap에 정규식을 넣습니다.

void Main()
{
    var lineLen = 25;
    var test1 = "Some random words like calendar boat and breathe.\nAnd an extra line.\n\n\nAnd here's one that has to break in the middle because there are no spaces:\n"
        + String.Join("", Enumerable.Range(1, lineLen + 5).Select(i => (i % 10).ToString()));

    var test2 = test1.Replace("\n","\r\n");

    StringHelper.StringRuler(lineLen).Dump("ruler");
    String.Join("\n", test1.WordWrap(lineLen)).Dump("test 1");
    String.Join("\r\n", test2.WordWrap(lineLen)).Dump("test 2");
}

public static class StringHelper {

    public static IEnumerable<String> WordWrap(this string source, int lineLength) {
        return new Regex(
            @"(?:[^\r\n]{1,lineLength}(?=\s|$)|[^\r\n]{lineLength}|(?<=\n)\r?\n)"
                .Replace("lineLength", lineLength.ToString()))
            .Matches(source)
            .Cast<Match>()  // http://.com/a/7274451/555142
            .Select(m=>m.Value.Trim());
    }

    public static string StringRuler(int lineLength) {
        return 
            String.Join("", Enumerable.Range(1, lineLength)
                .Select(i => ((i % 10) == 0 ? (i / 10).ToString() : " "))) + "\n" 
            + String.Join("", Enumerable.Range(1, lineLength).Select(i => (i % 10).ToString())) + "\n" 
            + String.Join("", Enumerable.Range(1, lineLength).Select(i => "-")); 
    }

}

LinqPad 테스트 ( Instant Share ). 두 개의 테스트가 있는데 첫 번째는 \ n 줄 바꿈을위한 것이고 두 번째는 \ r \ n 줄 바꿈을위한 것입니다.

ruler

         1         2     
1234567890123456789012345
------------------------- 

test 1

Some random words like
calendar boat and
breathe.
And an extra line.


And here's one that has
to break in the middle
because there are no
spaces:
1234567890123456789012345
67890 


test 2

Some random words like
calendar boat and
breathe.
And an extra line.


And here's one that has
to break in the middle
because there are no
spaces:
1234567890123456789012345
67890 

이런 확장 메서드를 작성합니다.

var input = "This string is really long. There are a lot of words in it.\r\nHere's another line in the string that's also very long.";

var lines = input.SplitByLength(20).ToList();
public static partial class MyExtensions
{
    public static  IEnumerable<string> SplitByLength(this string input, int maxLen)
    {
        return Regex.Split(input, @"(.{1," + maxLen + @"})(?:\s|$)")
                    .Where(x => x.Length > 0)
                    .Select(x => x.Trim());
    }
}

산출

This string is
really long. There
are a lot of words
in it.
Here's another line
in the string that's
also very long.

첫 번째 패스에서 '\ r \ n'의 자리 표시자를 추가 한 다음 \ r \ n '자리 표시 자'값을 \ r \ n으로 바꾸고 마지막으로 세 번째 패스를 만들고 왼쪽 자리 표시자를 \ r \ n으로 바꿉니다. .

예를 들어 \ u0000을 자리 표시 자로 사용합니다.

물론 원래 문자열에 null이 포함되지 않은 경우에만 작동합니다.

    string text = "This string is really long. There are a lot of words in it.\r\nHere's another line in the string that's also very long.";
    Console.WriteLine(text);

    text = Regex.Replace(text, @"(?<=^|\G)(.{1,20}(\s|$))", "$1\u0000", RegexOptions.Multiline);
    // break added after original
    text = Regex.Replace(text, "\r\n\u0000", "\r\n", RegexOptions.Multiline);
    text = Regex.Replace(text, "\u0000", "\r\n", RegexOptions.Multiline);
    Console.WriteLine(text);




word-wrap