ลบช่องว่างภายในวงเล็บยกเว้นข้อความในเครื่องหมายคำพูด

Aug 19 2020

ฉันกำลังมองหา regex ที่สามารถลบช่องว่างเมื่อพวกเขาอยู่ระหว่างวงเล็บที่ตรงกันคือ(และ), ยกเว้นเมื่อมีช่องว่างภายในเครื่องหมายคำพูด ( 'หรือ") ภายในวงเล็บ

ขณะนี้ฉันมี regex \s+(?=[^(]*\))ซึ่งจะลบช่องว่างทั้งหมดที่พบระหว่างวงเล็บ ดังนั้นเมื่อมีช่องว่างในเครื่องหมายคำพูด

// 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"

โปรดทราบว่าเครื่องหมายวรรคตอนทั้งสองถูกสร้างขึ้นมาและนั่นเป็นสาเหตุที่ไม่ได้ผล เช่นเดียวกันกับวงเล็บ ฉันสงสัยว่านิพจน์ทั่วไปธรรมดาสามารถช่วยได้หรือไม่ แต่ 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")