문제

좋아, 나는 약간의 정리를하려는 멀티 라인 문자열이있다.

각 줄은 인용 된 텍스트의 큰 블록의 일부일 수도 있고 아닐 수도 있습니다. 예시:

This line is not quoted.
This part of the line is not quoted “but this is.”
This one is not quoted either.
“This entire line is quoted”
Not quoted.
“This line is quoted
and so is this one
and so is this one.”
This is not quoted “but this is
and so is this.”

나는 딱딱한 인용 선을 랩핑하지 않고, 즉 " r n"을 공간으로 바꾸지 만 곱슬 인용문 사이에만 교체 할 수있는 REGEX 교체가 필요합니다.

교체를 돌보는 방법은 다음과 같습니다.

This line is not quoted.
This part of the line is not quoted “but this is.”
This one is not quoted either.
“This entire line is quoted”
Not quoted.
“This line is quoted and so is this one and so is this one.”
This is not quoted “but this is and so is this.”

(마지막 두 줄이 입력 텍스트에서 여러 줄이 어떻게 된 지에 유의하십시오.)

제약

  • 이상적으로는 단일 Regex 교체 호출이 필요합니다
  • .NET Regex 라이브러리 사용
  • 인용문은입니다 언제나 Plain Ol 'Double Ticks ( ")가 아닌 시작/종료 곱슬 인용문.

중요한 제약

이것은 직접 .NET 코드가 아니며 Regex.Replace를 통해 호출되는 "SearchFor/ReplaceWith"문자열 테이블을 채우고 있습니다. 매치 평가자, 캡처 된 그룹을 통한 루핑 등과 같은 사용자 정의 코드를 추가 할 수있는 기능이 없습니다.

지금까지의 현재 답변, 라인을 따라 무언가 :

r.Replace("(?<=“)\r\n(?=”)", " ")

분명히, 나는 아직 가까이 있지 않습니다.

동일한 논리가 프로그래밍 코드에서 블록 주석의 색상 코딩에 적용될 수 있습니다. 블록 주석 내부의 모든 것은 주석 외부의 물건과 동일한 방식으로 취급되지 않습니다. (시작/끝 블록 주석 Delimiters는 문자 그대로 문자열 내에 합법적으로 존재할 수 있기 때문에 코드는 조금 까다 롭습니다. 여기서 처리 할 필요가 없습니다.)

도움이 되었습니까?

해결책

모든 Curly 인용문이 올바르게 균형을 이루었다고 가정하면이 동선은 원하는대로해야합니다.

@"[\r\n]+(?=[^“”]*”)"

그만큼 [\r\n]+ 모든 유형의 하나 이상의 라인 분리기 (닉스), dos ( r n) 또는 구형 Mac ( r)의 하나 이상의 라인 분리기와 일치합니다. 그런 다음 Lookahead는 가까운 사원이 있으며 여기저기서 개방형 인용문이 없다고 주장합니다. 그런 다음 교체 텍스트는 간단한 공간 문자가 될 수 있습니다.

다른 팁

NB : Regexes를 테스트하기 위해 사용합니다 http://gskinner.com/regexr/ 매우 유용합니다.

나는 당신이 정의되지 않은 수의 신생을 대체 할 단일 표현을 쓸 수 있다고 생각하지 않습니다. 그러나 하나 또는 여러 가지를 대체 할 수있는 표현을 작성하고 반복적으로 실행하거나 하나의 인용 된 섹션 내에있는 최대의 최신 수를 처리하기 위해 작성할 수 있습니다.

먼저 표현식이 라인 별 대신 전체 입력 문자열과 일치하도록 단일 라인 모드를 원합니다. 표현이 시작될 때 이것을 켜십시오.

(?s)

그런 다음 시작 인용문과 일치하는 외관 표현식을 원합니다.

(?<=“)

그리고 최종 인용문과 일치하는 모습 :

(?=”)

이제 일부 텍스트, 새로운 라인, 텍스트와 일치하는 표현식이 있습니다.

([^”\r]*)\r?([^”\r]*)

Newline 주변의 텍스트 비트에 대한 두 개의 캡처 그룹이 있으므로 해당 텍스트를 대체 표현식에 포함시킬 수 있습니다. 이것은 인용문 내에 하나의 새로운 라인 만있는 텍스트와 일치합니다. 이것을 두 개의 newlines로 확장하려면 다른 선택적 Newline과 다음 텍스트를 추가하십시오.

(?s)(?<=“)([^”\r]*)\r?([^”\r]*)\r?([^”\r]*)(?=”)

당신은 이것을 당신이 생각하는만큼 많은 새로운 라인에 맞게 이것을 확장 할 수 있습니다. 완벽하지는 않지만 아마도 충분합니다. 또는 텍스트에서 표현식을 반복적으로 실행할 수 있다면 한 번에 하나의 표현식을 교체하십시오.

표현을 다음과 같이 남겨 둡니다.

r.Replace("(?s)(?<=“)([^”\r]*)\r?([^”\r]*)", "$1 $2")

(그룹 2가 일치하지 않더라도 텍스트 후 공간을 추가 할 수 있기 때문에 이것은 정확하지 않습니다 ... 그러나 시작입니다)

그래서해야 할 일은 오프닝 견적으로 시작하여 문자열을 찾는 것입니다. ~ 아니다 마감 견적 또는 r n 문자를 포함하고 일련의 일련의 r n 문자가 이어지고 터미널 r n 문자를 제외한 모든 것을 캡처하고 전체 일치를 캡처 된 부분으로 바꿉니다.

- Markusq

가장 간단한 방법은 인용 된 섹션과 일치하는 것입니다. “(?s:.*?)” 그리고 a Matchevaluator 최신 라인을 제거합니다. MatchEvaluator 코드는 간단 할 수 있습니다

Replace(@"\s+", " ");

물론, 당신은 실제로 최신 라인을 포함하는 인용 된 섹션 만 일치하도록 이것을 개선 할 수 있고, 모든 공백 대신 해당 섹션 내에서 최신 라인 만 교체 할 수 있지만, 노력할 가치가 없을 것입니다.

설명한 한계 내에서 원하는 것을 할 수 없습니다.

증거:

  • 고정 된 교체 테이블은 교체 할 고정 된 수의 통화를 실행합니다 (이 N 호출)
  • 각 교체는 고정 된 수의 라인 브레이크 만 제거 할 수 있습니다 (이 번호 M 호출).

그러므로

  • m*n+1 라인 브레이크가있는 인용 된 블록은 제대로 처리되지 않습니다.

설정의 전력 (예 :보다 복잡한 교체, 재귀 교체, 무기한 반복 플래그 또는 ...?)을 허용 하여이 작업을 엔진으로 수행 할 수 없다는 사실을 수용해야합니다.

- Markusq

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top