따옴표 안의 텍스트를 제외하고 괄호 안의 공백을 제거하십시오.

Aug 19 2020

나는 그들이 일치하는 대괄호, 즉 사이에있을 때 공백을 제거 할 수있는 정규식을 찾고 있어요 (하고 ), 제외 따옴표 (내부에 공간이있는 경우 '") 내부 브래킷.

현재 \s+(?=[^(]*\))괄호 사이에있는 모든 공백을 제거 하는 regex 가 있습니다. 따옴표 안에 공백이있을 때도 마찬가지입니다.

// My input
do something with(in = 1, text='some text with spaces' , text2="also has spaces")

// My current output
do something with(in=1,text='sometextwithspaces',text2="alsohasspaces")

// My desired output
do something with(in=1,text='some text with spaces',text2="also has spaces")

더욱이:

  • 인용 부호는 괄호 안에서만 찾을 수 있습니다.
  • 있을 수 있습니다 "' '텍스트 : text='text with " inside'는없이 \이스케이프 문자.
  • 있을 수 있습니다 '" "텍스트 : text="text with ' inside"는없이 \이스케이프 문자.
  • 문자열의 따옴표 앞에는 이스케이프 문자 가 없습니다 .text='This is \" not there'

정규식 패턴에 대한 몇 가지 질문이 있다는 것을 알고 있지만 트릭을 수행하는 질문을 찾을 수 없습니다. 내가 시도한 많은 것들 중에는 (까지 '또는와 "함께 만 물건을 찾을 수 \s+(?=[^("]*[\)"])있기를 기대했지만 여전히 "와 사이에 공백이 "있습니다.

누군가 나를 올바른 방향으로 가리킬 수 있습니까?

답변

1 AbdessabourMtk Aug 19 2020 at 19:06

사용한 정규식을 약간 수정했습니다.

# match a space or more 
# if the fol
(?<!['"][^,]*)\s+(?=[^(]*\))|\s+(?![^,]*['"])(?=[^(]*\))

정규식은 두 부분으로 나뉩니다. 정규식은 다음 중 하나와 일치합니다.

  1. 첫 번째 부분 은 따옴표 ( )가 앞에 나오지 않고 닫는 괄호가 뒤에 오는 경우 (?<!['"][^,]*)\s+(?=[^(]*\))가능한 한 많은 공백과 일치 합니다.\s+'"(?<!['"][^,]*)(?=[^(]*\))
  2. 두 번째 부분 은 따옴표로 이어지지 않고 닫는 괄호가 뒤에 오는 경우에만 \s+(?![^,]*['"])(?=[^(]*\))가능한 한 많은 공백과 일치 합니다.\s+(?![^,]*['"])(?=[^(]*\))

여기서 테스트 할 수 있습니다.

2 DmitryBychenko Aug 19 2020 at 02:27

글쎄요, 당신은 종류의 인용문 을 가지고 "있고 '당신은 인용문 을 다루어야합니다 .

  abc"def pqr' ijk" "klm ' xyz"

참고 아포스트로피가 enquoted하고 일을하지 않는 이유가있다. 대괄호 와 동일합니다 . 간단한 정규식이 여기에서 도움이 될 수 있을지 의심 스럽지만 Finite State Machine은 다음을 수행 할 수 있습니다.

private static string RemoveSpaces(string value) {
  if (string.IsNullOrEmpty(value))
    return value;

  bool inQuotation = false;
  bool inApostroph = false;
  int bracketCount = 0;
  int escapeCount = 0;
  StringBuilder result = new StringBuilder(value.Length);

  foreach (char c in value) {
    if (inQuotation) {
      result.Append(c);
      inQuotation = c != '"' || (escapeCount % 2 != 0);
    }
    else if (inApostroph) {
      result.Append(c);
      inApostroph = c != '\'' || (escapeCount % 2 != 0);
    }
    else {
      if (c != ' ' || bracketCount <= 0)
        result.Append(c);

      if (c == '(')
        bracketCount += 1;
      else if (bracketCount == ')')
        bracketCount -= 1;

      inQuotation = c == '"' && (escapeCount % 2 == 0);
      inApostroph = c == '\'' && (escapeCount % 2 == 0);
    }

    escapeCount = c == '\\' ? escapeCount + 1 : 0;
  }
  return result.ToString();
}

데모:

string test =
  @"do something with(in = 1, text='some text with spaces' , text2=""also has spaces"")";

Console.WriteLine(RemoveSpaces(test));

결과:

do something with(in=1,text='some text with spaces',text2="also has spaces")